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,1377 @@
|
|
|
1
|
+
"""
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import datetime
|
|
7
|
+
import decimal
|
|
8
|
+
from collections.abc import Iterable
|
|
9
|
+
from typing import Any, cast
|
|
10
|
+
|
|
11
|
+
from arelle import ModelDocument
|
|
12
|
+
from arelle.XbrlConst import xhtml
|
|
13
|
+
from arelle.typing import TypeGetText
|
|
14
|
+
from arelle.ValidateXbrl import ValidateXbrl
|
|
15
|
+
from arelle.utils.PluginHooks import ValidationHook
|
|
16
|
+
from arelle.utils.validate.Decorator import validation
|
|
17
|
+
from arelle.utils.validate.Validation import Validation
|
|
18
|
+
from arelle.XmlValidateConst import VALID
|
|
19
|
+
from . import errorOnDateFactComparison, getFactsWithDimension, getFactsGroupedByContextId, getFactsWithoutDimension, groupFactsByContextHash, \
|
|
20
|
+
minimumRequiredFactsFound, consolidatedDimensionExists
|
|
21
|
+
from ..PluginValidationDataExtension import PluginValidationDataExtension
|
|
22
|
+
from ..ValidationPluginExtension import DANISH_CURRENCY_ID, ROUNDING_MARGIN, PERSONNEL_EXPENSE_THRESHOLD, REQUIRED_DISCLOSURE_OF_EQUITY_FACTS, REQUIRED_STATEMENT_OF_CHANGES_IN_EQUITY_FACTS
|
|
23
|
+
from ..DisclosureSystems import MULTI_TARGET_DISCLOSURE_SYSTEMS, STAND_ALONE_DISCLOSURE_SYSTEMS
|
|
24
|
+
|
|
25
|
+
_: TypeGetText
|
|
26
|
+
|
|
27
|
+
@validation(
|
|
28
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
29
|
+
)
|
|
30
|
+
def rule_fr1(
|
|
31
|
+
pluginData: PluginValidationDataExtension,
|
|
32
|
+
val: ValidateXbrl,
|
|
33
|
+
*args: Any,
|
|
34
|
+
**kwargs: Any,
|
|
35
|
+
) -> Iterable[Validation]:
|
|
36
|
+
"""
|
|
37
|
+
DBA.FR1: First and last name of the conductor for the general meeting or person who takes the conductor's place is missing
|
|
38
|
+
Companies that hold a general meeting and therefore provide a general meeting date
|
|
39
|
+
(gsd:DateOfGeneralMeeting) must also provide the name of the director
|
|
40
|
+
(gsd:NameAndSurnameOfChairmanOfGeneralMeeting).
|
|
41
|
+
"""
|
|
42
|
+
meetingFacts = val.modelXbrl.factsByQname.get(pluginData.dateOfGeneralMeetingQn, set())
|
|
43
|
+
if len(meetingFacts) > 0:
|
|
44
|
+
chairmanFacts = val.modelXbrl.factsByQname.get(pluginData.nameAndSurnameOfChairmanOfGeneralMeetingQn, set())
|
|
45
|
+
if len(chairmanFacts) == 0:
|
|
46
|
+
yield Validation.error(
|
|
47
|
+
codes="DBA.FR1",
|
|
48
|
+
msg=_("First and last name of the conductor for the general meeting or person who takes the conductor's place is missing"),
|
|
49
|
+
modelObject=[val.modelXbrl.modelDocument]
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@validation(
|
|
54
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
55
|
+
)
|
|
56
|
+
def rule_fr7(
|
|
57
|
+
pluginData: PluginValidationDataExtension,
|
|
58
|
+
val: ValidateXbrl,
|
|
59
|
+
*args: Any,
|
|
60
|
+
**kwargs: Any,
|
|
61
|
+
) -> Iterable[Validation]:
|
|
62
|
+
"""
|
|
63
|
+
DBA.FR7: Date of approval of the annual report (gsd:DateOfApprovalOfAnnualReport)
|
|
64
|
+
must be after the end date of the Accounting Period (gsd:ReportingPeriodEndDate
|
|
65
|
+
with default TypeOfReportingPeriodDimension).
|
|
66
|
+
"""
|
|
67
|
+
return errorOnDateFactComparison(
|
|
68
|
+
val.modelXbrl,
|
|
69
|
+
fact1Qn=pluginData.reportingPeriodEndDateQn,
|
|
70
|
+
fact2Qn=pluginData.dateOfApprovalOfAnnualReportQn,
|
|
71
|
+
dimensionQn=pluginData.typeOfReportingPeriodDimensionQn,
|
|
72
|
+
code='DBA.FR7',
|
|
73
|
+
message=_("Date of approval of the annual report='%(fact2)s' "
|
|
74
|
+
"must be after the end date of the accounting period='%(fact1)s'"),
|
|
75
|
+
assertion=lambda endDate, approvalDate: endDate < approvalDate,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@validation(
|
|
80
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
81
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
82
|
+
)
|
|
83
|
+
def rule_fr20(
|
|
84
|
+
pluginData: PluginValidationDataExtension,
|
|
85
|
+
val: ValidateXbrl,
|
|
86
|
+
*args: Any,
|
|
87
|
+
**kwargs: Any,
|
|
88
|
+
) -> Iterable[Validation]:
|
|
89
|
+
"""
|
|
90
|
+
DBA.FR20: The annual report is missing a management endorsement. An annual report must always contain a management
|
|
91
|
+
endorsement if the company has more than one management member or if the company prepares an annual report according
|
|
92
|
+
to accounting class D.
|
|
93
|
+
"""
|
|
94
|
+
modelXbrl = val.modelXbrl
|
|
95
|
+
for concept_qn in pluginData.managementEndorsementQns:
|
|
96
|
+
facts = modelXbrl.factsByQname.get(concept_qn, set())
|
|
97
|
+
for fact in facts:
|
|
98
|
+
if fact.xValid >= VALID and not fact.isNil:
|
|
99
|
+
return
|
|
100
|
+
yield Validation.error(
|
|
101
|
+
codes="DBA.FR20",
|
|
102
|
+
msg=_("The annual report does not contain a management endorsement. Please tag one of the following elements: {}").format(
|
|
103
|
+
[qn.localName for qn in pluginData.managementEndorsementQns]
|
|
104
|
+
),
|
|
105
|
+
modelObject=val.modelXbrl.modelDocument
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@validation(
|
|
110
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
111
|
+
)
|
|
112
|
+
def rule_fr24(
|
|
113
|
+
pluginData: PluginValidationDataExtension,
|
|
114
|
+
val: ValidateXbrl,
|
|
115
|
+
*args: Any,
|
|
116
|
+
**kwargs: Any,
|
|
117
|
+
) -> Iterable[Validation]:
|
|
118
|
+
"""
|
|
119
|
+
DBA.FR24: When cmn:TypeOfAuditorAssistance is "Revisionspåtegning" or "Auditor's report on audited financial statements"
|
|
120
|
+
then arr:DescriptionOfQualificationsOfAuditedFinancialStatements must not contain the following text:
|
|
121
|
+
- 'har ikke givet anledning til forbehold'
|
|
122
|
+
- 'has not given rise to reservations'
|
|
123
|
+
"""
|
|
124
|
+
modelXbrl = val.modelXbrl
|
|
125
|
+
type_of_auditors_assistance_facts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
|
|
126
|
+
for auditor_fact in type_of_auditors_assistance_facts:
|
|
127
|
+
if (auditor_fact.xValid >= VALID and
|
|
128
|
+
(auditor_fact.xValue == pluginData.auditedFinancialStatementsDanish or
|
|
129
|
+
auditor_fact.xValue == pluginData.auditedFinancialStatementsEnglish)):
|
|
130
|
+
description_facts = modelXbrl.factsByQname.get(pluginData.descriptionOfQualificationsOfAuditedFinancialStatementsQn, set())
|
|
131
|
+
for description_fact in description_facts:
|
|
132
|
+
if description_fact.xValid >= VALID:
|
|
133
|
+
for text in pluginData.hasNotGivenRiseToReservationsText:
|
|
134
|
+
if text in str(description_fact.xValue):
|
|
135
|
+
yield Validation.error(
|
|
136
|
+
codes="DBA.FR24",
|
|
137
|
+
msg=_("The value of DescriptionOfQualificationsOfAuditedFinancialStatements must not "
|
|
138
|
+
"contain the text: \'{}\', when TypeOfAuditorAssistance is set to \'Revisionspåtegning\' "
|
|
139
|
+
"or \'Auditor's report on audited financial statements\'").format(text),
|
|
140
|
+
modelObject=description_fact
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@validation(
|
|
145
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
146
|
+
)
|
|
147
|
+
def rule_fr25(
|
|
148
|
+
pluginData: PluginValidationDataExtension,
|
|
149
|
+
val: ValidateXbrl,
|
|
150
|
+
*args: Any,
|
|
151
|
+
**kwargs: Any,
|
|
152
|
+
) -> Iterable[Validation]:
|
|
153
|
+
"""
|
|
154
|
+
DBA.FR25: When cmn:TypeOfAuditorAssistance is "Erklæring om udvidet gennemgang" or "Auditor's report on extended review"
|
|
155
|
+
then arr:DescriptionOfQualificationsOfFinancialStatementsExtendedReview must not contain the following text:
|
|
156
|
+
- 'har ikke givet anledning til forbehold'
|
|
157
|
+
- 'has not given rise to reservations'
|
|
158
|
+
"""
|
|
159
|
+
modelXbrl = val.modelXbrl
|
|
160
|
+
type_of_auditors_assistance_facts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
|
|
161
|
+
for auditor_fact in type_of_auditors_assistance_facts:
|
|
162
|
+
if (auditor_fact.xValid >= VALID and
|
|
163
|
+
(auditor_fact.xValue == pluginData.auditedExtendedReviewDanish or
|
|
164
|
+
auditor_fact.xValue == pluginData.auditedExtendedReviewEnglish)):
|
|
165
|
+
description_facts = modelXbrl.factsByQname.get(pluginData.descriptionOfQualificationsOfFinancialStatementsExtendedReviewQn, set())
|
|
166
|
+
for description_fact in description_facts:
|
|
167
|
+
if description_fact.xValid >= VALID:
|
|
168
|
+
for text in pluginData.hasNotGivenRiseToReservationsText:
|
|
169
|
+
if text in str(description_fact.xValue):
|
|
170
|
+
yield Validation.error(
|
|
171
|
+
codes="DBA.FR25",
|
|
172
|
+
msg=_("The value of DescriptionOfQualificationsOfFinancialStatementsExtendedReview must not "
|
|
173
|
+
"contain the text: \'{}\', when TypeOfAuditorAssistance is set to \'Erklæring om udvidet "
|
|
174
|
+
"gennemgang\' or \'Auditor's report on extended review\'").format(text),
|
|
175
|
+
modelObject=description_fact
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@validation(
|
|
181
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
182
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
183
|
+
)
|
|
184
|
+
def rule_fr33(
|
|
185
|
+
pluginData: PluginValidationDataExtension,
|
|
186
|
+
val: ValidateXbrl,
|
|
187
|
+
*args: Any,
|
|
188
|
+
**kwargs: Any,
|
|
189
|
+
) -> Iterable[Validation]:
|
|
190
|
+
"""
|
|
191
|
+
DBA.FR33: For groups in accounting classes C and D, either Statement of changes in equity [hierarchy:fsa:StatementOfChangesInEquity] must have a minimum of three fields filled in from
|
|
192
|
+
[hierarchy:fsa:StatementOfChangesInEquity] or two fields in
|
|
193
|
+
Information on equity [hierarchy:fsa:DisclosureOfEquity].
|
|
194
|
+
"""
|
|
195
|
+
reportingClass = False
|
|
196
|
+
classOfReportingEntityFacts = val.modelXbrl.factsByQname.get(pluginData.classOfReportingEntityQn, set())
|
|
197
|
+
for fact in classOfReportingEntityFacts:
|
|
198
|
+
if fact is not None and fact.xValid >= VALID:
|
|
199
|
+
if fact.xValue in pluginData.cClassOfReportingEntityEnums or fact.xValue in pluginData.dClassOfReportingEntityEnums:
|
|
200
|
+
reportingClass = True
|
|
201
|
+
break
|
|
202
|
+
if not reportingClass:
|
|
203
|
+
reportingClass = any(
|
|
204
|
+
fact and fact.xValid >= VALID
|
|
205
|
+
for fact in val.modelXbrl.factsByQname.get(pluginData.selectedElementsFromReportingClassCQn, set())
|
|
206
|
+
)
|
|
207
|
+
if not reportingClass:
|
|
208
|
+
reportingClass = any(
|
|
209
|
+
fact and fact.xValid >= VALID
|
|
210
|
+
for fact in val.modelXbrl.factsByQname.get(pluginData.selectedElementsFromReportingClassDQn, set())
|
|
211
|
+
)
|
|
212
|
+
if reportingClass:
|
|
213
|
+
if not minimumRequiredFactsFound(val.modelXbrl, pluginData.disclosureOfEquityQns, REQUIRED_DISCLOSURE_OF_EQUITY_FACTS):
|
|
214
|
+
if not minimumRequiredFactsFound(val.modelXbrl, pluginData.statementOfChangesInEquityQns, REQUIRED_STATEMENT_OF_CHANGES_IN_EQUITY_FACTS):
|
|
215
|
+
yield Validation.error(
|
|
216
|
+
codes="DBA.FR33",
|
|
217
|
+
msg=_("For groups in accounting classes C and D, either Statement of Changes in Equity '[hierarchy:fsa:StatementOfChangesInEquity]' must have a minimum of three fields filled in "
|
|
218
|
+
"Or two fields in Information on Equity [hierarchy:fsa:DisclosureOfEquity] ."),
|
|
219
|
+
modelObject=val.modelXbrl.modelDocument
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@validation(
|
|
224
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
225
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
226
|
+
)
|
|
227
|
+
def rule_fr34(
|
|
228
|
+
pluginData: PluginValidationDataExtension,
|
|
229
|
+
val: ValidateXbrl,
|
|
230
|
+
*args: Any,
|
|
231
|
+
**kwargs: Any,
|
|
232
|
+
) -> Iterable[Validation]:
|
|
233
|
+
"""
|
|
234
|
+
DBA.FR34: If Equity does not equal 0 more fields are required. At least one field must be filled in on the balance sheet in addition to equity:
|
|
235
|
+
Assets, NoncurrentAssets, CurrentAssets, LongtermLiabilitiesOtherThanProvisions, ShorttermLiabilitiesOtherThanProvisions, LiabilitiesOtherThanProvisions, LiabilitiesAndEquity
|
|
236
|
+
"""
|
|
237
|
+
equityFacts = val.modelXbrl.factsByQname.get(pluginData.equityQn, set())
|
|
238
|
+
nonZeroEquityFacts = []
|
|
239
|
+
for fact in equityFacts:
|
|
240
|
+
if fact.xValid >= VALID:
|
|
241
|
+
if fact.xValue != 0:
|
|
242
|
+
nonZeroEquityFacts.append(fact)
|
|
243
|
+
if nonZeroEquityFacts:
|
|
244
|
+
otherRequiredFactsQnames = [
|
|
245
|
+
pluginData.assetsQn, pluginData.noncurrentAssetsQn, pluginData.longtermLiabilitiesOtherThanProvisionsQn,
|
|
246
|
+
pluginData.shorttermLiabilitiesOtherThanProvisionsQn, pluginData.liabilitiesOtherThanProvisionsQn, pluginData.liabilitiesAndEquityQn
|
|
247
|
+
]
|
|
248
|
+
hasEquityRequiredFacts = any(val.modelXbrl.factsByQname.get(factQname, set()) for factQname in otherRequiredFactsQnames)
|
|
249
|
+
if not hasEquityRequiredFacts:
|
|
250
|
+
yield Validation.error(
|
|
251
|
+
codes="DBA.FR34",
|
|
252
|
+
msg=_("If Equity is filled in and is not zero, at least one other field must also be filled in: "
|
|
253
|
+
"Assets, NoncurrentAssets, CurrentAssets, LongtermLiabilitiesOtherThanProvisions, ShorttermLiabilitiesOtherThanProvisions, "
|
|
254
|
+
"LiabilitiesOtherThanProvisions, LiabilitiesAndEquity."),
|
|
255
|
+
modelObject=nonZeroEquityFacts
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@validation(
|
|
260
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
261
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
262
|
+
)
|
|
263
|
+
def rule_fr35(
|
|
264
|
+
pluginData: PluginValidationDataExtension,
|
|
265
|
+
val: ValidateXbrl,
|
|
266
|
+
*args: Any,
|
|
267
|
+
**kwargs: Any,
|
|
268
|
+
) -> Iterable[Validation]:
|
|
269
|
+
"""
|
|
270
|
+
DBA.FR35: The annual report does not contain a section on applied accounting practices. The annual report must
|
|
271
|
+
contain a section on the accounting practices used.
|
|
272
|
+
"""
|
|
273
|
+
modelXbrl = val.modelXbrl
|
|
274
|
+
noDimensionFacts = set()
|
|
275
|
+
consolidatedDimensionFacts = set()
|
|
276
|
+
checkConsolidated = consolidatedDimensionExists(modelXbrl, pluginData.consolidatedSoloDimensionQn)
|
|
277
|
+
for concept_qn in pluginData.accountingPolicyConceptQns:
|
|
278
|
+
facts = modelXbrl.factsByQname.get(concept_qn, set())
|
|
279
|
+
for fact in facts:
|
|
280
|
+
if fact.xValid >= VALID and not fact.isNil:
|
|
281
|
+
if not fact.context.scenDimValues:
|
|
282
|
+
noDimensionFacts.add(fact)
|
|
283
|
+
if pluginData.consolidatedSoloDimensionQn in [dim.qname for dim in fact.context.scenDimValues.keys()]:
|
|
284
|
+
consolidatedDimensionFacts.add(fact)
|
|
285
|
+
if not checkConsolidated and len(noDimensionFacts) == 0:
|
|
286
|
+
yield Validation.error(
|
|
287
|
+
codes="DBA.FR35.noDimension",
|
|
288
|
+
msg=_("The annual report does not contain information on applied accounting practices. Please tag one of the following elements without a dimension: {}").format(
|
|
289
|
+
[qn.localName for qn in pluginData.accountingPolicyConceptQns]
|
|
290
|
+
),
|
|
291
|
+
modelObject=val.modelXbrl.modelDocument
|
|
292
|
+
)
|
|
293
|
+
if checkConsolidated and len(consolidatedDimensionFacts) == 0:
|
|
294
|
+
yield Validation.error(
|
|
295
|
+
codes="DBA.FR35.consolidatedSoloDimension",
|
|
296
|
+
msg=_("The annual report does not contain information on applied accounting practices. Please tag one of the following elements with the ConsolidatedSoloDimension: {}").format(
|
|
297
|
+
[qn.localName for qn in pluginData.accountingPolicyConceptQns]
|
|
298
|
+
),
|
|
299
|
+
modelObject=val.modelXbrl.modelDocument
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
@validation(
|
|
304
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
305
|
+
)
|
|
306
|
+
def rule_fr36(
|
|
307
|
+
pluginData: PluginValidationDataExtension,
|
|
308
|
+
val: ValidateXbrl,
|
|
309
|
+
*args: Any,
|
|
310
|
+
**kwargs: Any,
|
|
311
|
+
) -> Iterable[Validation]:
|
|
312
|
+
"""
|
|
313
|
+
DBA.FR36: arr:DescriptionsOfQualificationsOfReviewedFinancialStatements must not contain the following text:
|
|
314
|
+
- 'har ikke givet anledning til forbehold'
|
|
315
|
+
- 'has not given rise to reservations'
|
|
316
|
+
"""
|
|
317
|
+
modelXbrl = val.modelXbrl
|
|
318
|
+
description_facts = modelXbrl.factsByQname.get(pluginData.descriptionsOfQualificationsOfReviewedFinancialStatementsQn, set())
|
|
319
|
+
for description_fact in description_facts:
|
|
320
|
+
if description_fact.xValid >= VALID:
|
|
321
|
+
for text in pluginData.hasNotGivenRiseToReservationsText:
|
|
322
|
+
if text in str(description_fact.xValue):
|
|
323
|
+
yield Validation.error(
|
|
324
|
+
codes="DBA.FR36",
|
|
325
|
+
msg=_("The value of DescriptionsOfQualificationsOfReviewedFinancialStatements must not contain the text: \'{}\'".format(text)),
|
|
326
|
+
modelObject=description_fact
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
@validation(
|
|
331
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
332
|
+
)
|
|
333
|
+
def rule_fr37(
|
|
334
|
+
pluginData: PluginValidationDataExtension,
|
|
335
|
+
val: ValidateXbrl,
|
|
336
|
+
*args: Any,
|
|
337
|
+
**kwargs: Any,
|
|
338
|
+
) -> Iterable[Validation]:
|
|
339
|
+
"""
|
|
340
|
+
DBA.FR37: arr:DescriptionOfQualificationsOfAssuranceEngagementPerformed must not contain the following text:
|
|
341
|
+
- 'har ikke givet anledning til forbehold'
|
|
342
|
+
- 'has not given rise to reservations'
|
|
343
|
+
"""
|
|
344
|
+
modelXbrl = val.modelXbrl
|
|
345
|
+
description_facts = modelXbrl.factsByQname.get(pluginData.descriptionOfQualificationsOfAssuranceEngagementPerformedQn, set())
|
|
346
|
+
for description_fact in description_facts:
|
|
347
|
+
if description_fact.xValid >= VALID:
|
|
348
|
+
for text in pluginData.hasNotGivenRiseToReservationsText:
|
|
349
|
+
if text in str(description_fact.xValue):
|
|
350
|
+
yield Validation.error(
|
|
351
|
+
codes="DBA.FR37",
|
|
352
|
+
msg=_("The value of DescriptionOfQualificationsOfAssuranceEngagementPerformed must not contain the text: \'{}\'".format(text)),
|
|
353
|
+
modelObject=description_fact
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
@validation(
|
|
358
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
359
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
360
|
+
)
|
|
361
|
+
def rule_fr41(
|
|
362
|
+
pluginData: PluginValidationDataExtension,
|
|
363
|
+
val: ValidateXbrl,
|
|
364
|
+
*args: Any,
|
|
365
|
+
**kwargs: Any,
|
|
366
|
+
) -> Iterable[Validation]:
|
|
367
|
+
"""
|
|
368
|
+
DBA.FR41: Failure to fill in 'Tax on profit for the year' or 'Tax on ordinary profit'
|
|
369
|
+
|
|
370
|
+
If the result for the year is positive(fsa:ProfitLoss) (defined as greater than DKK 1000),
|
|
371
|
+
either Tax on the year's result (fsa:TaxExpense) or Tax on ordinary result
|
|
372
|
+
(fsa:TaxExpenseOnOrdinaryActivities) must be filled in.
|
|
373
|
+
|
|
374
|
+
The control does not look at I/S (partnership), K/S (limited partnership) and P/S
|
|
375
|
+
(partner company, like an LLC). (based on what legal form the identification number is
|
|
376
|
+
registered as in the business register).
|
|
377
|
+
|
|
378
|
+
Implementation: For each reporting period context that has a fsa:ProfitLoss fact above
|
|
379
|
+
the threshold, check if there is either a non-nil fsa:TaxExpense or fsa:TaxExpenseOnOrdinaryActivities
|
|
380
|
+
fact in the same context. If not, trigger an error.
|
|
381
|
+
"""
|
|
382
|
+
|
|
383
|
+
# TODO: There appears to be criteria that exempt some filings from this rule.
|
|
384
|
+
# The criteria is based on the legal form of the company, which may or may not be
|
|
385
|
+
# something we can determine from the identification number and/or other instance data.
|
|
386
|
+
# Once we determine if/how that criteria can be implemented, we can add it here.
|
|
387
|
+
|
|
388
|
+
modelXbrl = val.modelXbrl
|
|
389
|
+
contextIds = {c.id for c in pluginData.getCurrentAndPreviousReportingPeriodContexts(modelXbrl)}
|
|
390
|
+
contextMap = {k: v for k, v in pluginData.contextFactMap(modelXbrl).items() if k in contextIds}
|
|
391
|
+
for contextId, factMap in contextMap.items():
|
|
392
|
+
profitLossFact = factMap.get(pluginData.profitLossQn)
|
|
393
|
+
if profitLossFact is None:
|
|
394
|
+
continue
|
|
395
|
+
|
|
396
|
+
if profitLossFact.xValid >= VALID and cast(decimal.Decimal, profitLossFact.xValue) <= pluginData.positiveProfitThreshold:
|
|
397
|
+
continue
|
|
398
|
+
taxExpenseFact = factMap.get(pluginData.taxExpenseQn)
|
|
399
|
+
if taxExpenseFact is not None and not taxExpenseFact.isNil:
|
|
400
|
+
continue
|
|
401
|
+
taxExpenseOnOrdinaryActivitiesFact = factMap.get(pluginData.taxExpenseOnOrdinaryActivitiesQn)
|
|
402
|
+
if taxExpenseOnOrdinaryActivitiesFact is not None and not taxExpenseOnOrdinaryActivitiesFact.isNil:
|
|
403
|
+
continue
|
|
404
|
+
yield Validation.warning(
|
|
405
|
+
codes='DBA.FR41',
|
|
406
|
+
msg=_("The annual report does not contain information on tax "
|
|
407
|
+
"on the year's profit. If the profit for the year in the income "
|
|
408
|
+
"statement is positive, either 'Tax on profit for the year' or "
|
|
409
|
+
"'Tax on ordinary profit' must be filled in."),
|
|
410
|
+
modelObject=profitLossFact,
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
@validation(
|
|
415
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
416
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
417
|
+
)
|
|
418
|
+
def rule_fr48(
|
|
419
|
+
pluginData: PluginValidationDataExtension,
|
|
420
|
+
val: ValidateXbrl,
|
|
421
|
+
*args: Any,
|
|
422
|
+
**kwargs: Any,
|
|
423
|
+
) -> Iterable[Validation]:
|
|
424
|
+
"""
|
|
425
|
+
DBA.FR48: Annual reports with a start date of 1/1 2016 or later may not use the fields:
|
|
426
|
+
'Extraordinary result before tax',
|
|
427
|
+
'Extraordinary income',
|
|
428
|
+
'Extraordinary costs',
|
|
429
|
+
as §30 of the Annual Accounts Act is repealed."
|
|
430
|
+
"""
|
|
431
|
+
disallowedFactQnames = [pluginData.extraordinaryCostsQn, pluginData.extraordinaryIncomeQn, pluginData.extraordinaryResultBeforeTaxQn]
|
|
432
|
+
foundFacts = []
|
|
433
|
+
for factQname in disallowedFactQnames:
|
|
434
|
+
facts = val.modelXbrl.factsByQname.get(factQname, set())
|
|
435
|
+
if len(facts) > 0:
|
|
436
|
+
foundFacts.append(facts)
|
|
437
|
+
if len(foundFacts) > 0:
|
|
438
|
+
yield Validation.warning(
|
|
439
|
+
codes="DBA.FR48",
|
|
440
|
+
msg=_("Annual reports with a start date of 1/1 2016 or later must not use the fields: "
|
|
441
|
+
"'Extraordinary profit before tax', 'Extraordinary income', 'Extraordinary costs'."),
|
|
442
|
+
modelObject=foundFacts
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
@validation(
|
|
447
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
448
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
449
|
+
)
|
|
450
|
+
def rule_fr52(
|
|
451
|
+
pluginData: PluginValidationDataExtension,
|
|
452
|
+
val: ValidateXbrl,
|
|
453
|
+
*args: Any,
|
|
454
|
+
**kwargs: Any,
|
|
455
|
+
) -> Iterable[Validation]:
|
|
456
|
+
"""
|
|
457
|
+
DBA.FR52: Any usage of fsa:ProposedExtraordinaryDividendRecognisedInLiabilities is prohibited.
|
|
458
|
+
"""
|
|
459
|
+
modelXbrl = val.modelXbrl
|
|
460
|
+
facts = modelXbrl.factsByQname.get(pluginData.proposedExtraordinaryDividendRecognisedInLiabilitiesQn, set())
|
|
461
|
+
if len(facts) > 0:
|
|
462
|
+
yield Validation.warning(
|
|
463
|
+
codes='DBA.FR52',
|
|
464
|
+
msg=_("The concept ProposedExtraordinaryDividendRecognisedInLiabilities should not be used"),
|
|
465
|
+
modelObject=facts
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
@validation(
|
|
470
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
471
|
+
)
|
|
472
|
+
def rule_fr53(
|
|
473
|
+
pluginData: PluginValidationDataExtension,
|
|
474
|
+
val: ValidateXbrl,
|
|
475
|
+
*args: Any,
|
|
476
|
+
**kwargs: Any,
|
|
477
|
+
) -> Iterable[Validation]:
|
|
478
|
+
"""
|
|
479
|
+
DBA.FR53: Information is missing on the audit company's CVR no. and the audit firm's name.
|
|
480
|
+
|
|
481
|
+
The audit firm's CVR number and name of audit firm should be provided when (fsa:TypeOfAuditorAssistance) is
|
|
482
|
+
tagged with one of the following values:
|
|
483
|
+
- (Revisionspåtegning) / (Auditor's report on audited financial statements)
|
|
484
|
+
- (Erklæring om udvidet gennemgang) / (Auditor's report on extended review)
|
|
485
|
+
- (Den uafhængige revisors erklæringer (review)) / (The independent auditor's reports (Review))
|
|
486
|
+
- (Andre erklæringer med sikkerhed) / (The independent auditor's reports (Other assurance Reports))
|
|
487
|
+
"""
|
|
488
|
+
modelXbrl = val.modelXbrl
|
|
489
|
+
facts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
|
|
490
|
+
for fact in facts:
|
|
491
|
+
if fact.xValid >= VALID:
|
|
492
|
+
if fact.xValue in [
|
|
493
|
+
pluginData.auditedFinancialStatementsDanish,
|
|
494
|
+
pluginData.auditedFinancialStatementsEnglish,
|
|
495
|
+
pluginData.auditedExtendedReviewDanish,
|
|
496
|
+
pluginData.auditedExtendedReviewEnglish,
|
|
497
|
+
pluginData.independentAuditorsReportDanish,
|
|
498
|
+
pluginData.independentAuditorsReportEnglish,
|
|
499
|
+
pluginData.auditedAssuranceReportsDanish,
|
|
500
|
+
pluginData.auditedAssuranceReportsEnglish
|
|
501
|
+
]:
|
|
502
|
+
missing_concepts = []
|
|
503
|
+
cvr_facts = modelXbrl.factsByQname.get(pluginData.identificationNumberCvrOfAuditFirmQn, set())
|
|
504
|
+
auditor_name_facts = modelXbrl.factsByQname.get(pluginData.nameOfAuditFirmQn, set())
|
|
505
|
+
if len(cvr_facts) == 0:
|
|
506
|
+
missing_concepts.append(pluginData.identificationNumberCvrOfAuditFirmQn.localName)
|
|
507
|
+
if len(auditor_name_facts) == 0:
|
|
508
|
+
missing_concepts.append(pluginData.nameOfAuditFirmQn.localName)
|
|
509
|
+
if len(missing_concepts) > 0:
|
|
510
|
+
yield Validation.warning(
|
|
511
|
+
codes='DBA.FR53',
|
|
512
|
+
msg=_("The following concepts should be tagged: {} when {} is tagged with the value of {}").format(
|
|
513
|
+
",".join(missing_concepts),
|
|
514
|
+
pluginData.typeOfAuditorAssistanceQn.localName,
|
|
515
|
+
fact.xValue
|
|
516
|
+
),
|
|
517
|
+
modelObject=fact
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
@validation(
|
|
522
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
523
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
524
|
+
)
|
|
525
|
+
def rule_fr56(
|
|
526
|
+
pluginData: PluginValidationDataExtension,
|
|
527
|
+
val: ValidateXbrl,
|
|
528
|
+
*args: Any,
|
|
529
|
+
**kwargs: Any,
|
|
530
|
+
) -> Iterable[Validation]:
|
|
531
|
+
"""
|
|
532
|
+
DBA.FR56: Missing allocation of profit. The annual report must contain a
|
|
533
|
+
distribution of results.
|
|
534
|
+
|
|
535
|
+
Annual reports, etc. with a start date of 1/1 2016 or later must have a profit
|
|
536
|
+
allocation, if the profit (fsa:ProfitLoss) for the year is greater than 1000 or
|
|
537
|
+
less than -1000, cf. the Annual Accounts Act §§ 31 and 95 a.
|
|
538
|
+
"""
|
|
539
|
+
modelXbrl = val.modelXbrl
|
|
540
|
+
contextIds = {c.id for c in pluginData.getCurrentAndPreviousReportingPeriodContexts(modelXbrl)}
|
|
541
|
+
profitLossFactsMap = getFactsGroupedByContextId(modelXbrl, pluginData.profitLossQn)
|
|
542
|
+
distributionFactsMap = getFactsGroupedByContextId(
|
|
543
|
+
modelXbrl,
|
|
544
|
+
*pluginData.distributionOfResultsQns,
|
|
545
|
+
)
|
|
546
|
+
for contextId, profitLossFacts in profitLossFactsMap.items():
|
|
547
|
+
if contextId not in contextIds:
|
|
548
|
+
continue
|
|
549
|
+
profitLossFact = None
|
|
550
|
+
for fact in profitLossFacts:
|
|
551
|
+
if fact.xValid >= VALID:
|
|
552
|
+
profitLossValue = cast(decimal.Decimal, fact.xValue)
|
|
553
|
+
if not (-pluginData.positiveProfitThreshold <= profitLossValue <= pluginData.positiveProfitThreshold):
|
|
554
|
+
profitLossFact = fact
|
|
555
|
+
break
|
|
556
|
+
if profitLossFact is None:
|
|
557
|
+
continue
|
|
558
|
+
distributionFacts = distributionFactsMap.get(contextId, [])
|
|
559
|
+
valid = False
|
|
560
|
+
for distributionsResultDistributionFact in distributionFacts:
|
|
561
|
+
if not distributionsResultDistributionFact.isNil:
|
|
562
|
+
valid = True
|
|
563
|
+
break
|
|
564
|
+
if not valid:
|
|
565
|
+
yield Validation.warning(
|
|
566
|
+
codes='DBA.FR56',
|
|
567
|
+
msg=_("The annual report does not contain a profit distribution. "
|
|
568
|
+
"The annual report must contain a profit and loss statement with a "
|
|
569
|
+
"distribution of profits."),
|
|
570
|
+
modelObject=profitLossFact
|
|
571
|
+
)
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
@validation(
|
|
575
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
576
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
577
|
+
)
|
|
578
|
+
def rule_fr57(
|
|
579
|
+
pluginData: PluginValidationDataExtension,
|
|
580
|
+
val: ValidateXbrl,
|
|
581
|
+
*args: Any,
|
|
582
|
+
**kwargs: Any,
|
|
583
|
+
) -> Iterable[Validation]:
|
|
584
|
+
"""
|
|
585
|
+
DBA.FR57.MarkingOfPeriod(Error):
|
|
586
|
+
Previous accounting period is marked(fsa:PrecedingReportingPeriodStartDate), even though it is the first accounting period.
|
|
587
|
+
The company has marked the previous accounting period, even though it is the first accounting period. If the previous accounting period is marked,
|
|
588
|
+
the control expects comparative figures.
|
|
589
|
+
|
|
590
|
+
DBA.FR57.ProfitLoss(Error):
|
|
591
|
+
The profit for the year (fsa:ProfitLoss) in the income statement must be filled in
|
|
592
|
+
|
|
593
|
+
DBA.FR57.Equity(Error):
|
|
594
|
+
The equity (fsa:Equity) in the balance sheet must be filled in
|
|
595
|
+
|
|
596
|
+
DBA.FR57.Assets(Error):
|
|
597
|
+
Assets (fsa:Assets) must be stated and must not be negative
|
|
598
|
+
|
|
599
|
+
DBA.FR57.LiabilitiesAndEquity(Error):
|
|
600
|
+
Liabilities (fsa:LiabilitiesAndEquity) must be stated and must not be negative
|
|
601
|
+
|
|
602
|
+
DBA.FR57.Equality(Error):
|
|
603
|
+
Assets (fsa:Assets) must equal Liabilities (fsa:LiabilitiesAndEquity)
|
|
604
|
+
"""
|
|
605
|
+
currentStartDateFacts = getFactsWithDimension(val, pluginData.reportingPeriodStartDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
|
|
606
|
+
currentEndDateFacts = getFactsWithDimension(val, pluginData.reportingPeriodEndDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
|
|
607
|
+
currentGroupedFacts = groupFactsByContextHash(currentStartDateFacts.union(currentEndDateFacts))
|
|
608
|
+
precedingEndDateFacts = getFactsWithDimension(val, pluginData.precedingReportingPeriodEndDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
|
|
609
|
+
precedingStartDateFacts = getFactsWithDimension(val, pluginData.precedingReportingPeriodStartDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
|
|
610
|
+
precedingGroupedFacts = groupFactsByContextHash(precedingEndDateFacts.union(precedingStartDateFacts))
|
|
611
|
+
currentEndDateFact = None
|
|
612
|
+
currentStartDateFact = None
|
|
613
|
+
precedingStartDateFact = None
|
|
614
|
+
precedingEndDateFact = None
|
|
615
|
+
foundCurrentAssets = None
|
|
616
|
+
foundCurrentLiabilitiesAndEquity = None
|
|
617
|
+
foundPreviousAssets = None
|
|
618
|
+
foundPreviousLiabilitiesAndEquity = None
|
|
619
|
+
assetErrors = []
|
|
620
|
+
equityErrors = []
|
|
621
|
+
equalityErrorPairs = []
|
|
622
|
+
profitLossErrors = []
|
|
623
|
+
liabilitiesAndEquityErrors = []
|
|
624
|
+
negativeAssetFacts = []
|
|
625
|
+
negativeLiabilitiesAndEquityFacts = []
|
|
626
|
+
currentPeriodFound = any(len(facts) == 2 for facts in currentGroupedFacts.values())
|
|
627
|
+
precedingPeriodFound = any(len(facts) == 2 for facts in precedingGroupedFacts.values())
|
|
628
|
+
if precedingPeriodFound and not currentPeriodFound:
|
|
629
|
+
yield Validation.error(
|
|
630
|
+
codes="DBA.FR57.MarkingOfPeriod",
|
|
631
|
+
msg=_("The company has marked the previous accounting period, even though it is the first accounting period."),
|
|
632
|
+
)
|
|
633
|
+
elif currentPeriodFound:
|
|
634
|
+
assetsFacts = getFactsWithoutDimension(val, pluginData.assetsQn)
|
|
635
|
+
equityFacts = getFactsWithoutDimension(val, pluginData.equityQn)
|
|
636
|
+
profitLossFacts = getFactsWithoutDimension(val, pluginData.profitLossQn)
|
|
637
|
+
liabilitiesAndEquityFacts = getFactsWithoutDimension(val, pluginData.liabilitiesAndEquityQn)
|
|
638
|
+
for facts in currentGroupedFacts.values():
|
|
639
|
+
if len(facts) == 2:
|
|
640
|
+
for fact in facts:
|
|
641
|
+
if fact.qname == pluginData.reportingPeriodStartDateQn:
|
|
642
|
+
currentStartDateFact = fact
|
|
643
|
+
elif fact.qname == pluginData.reportingPeriodEndDateQn:
|
|
644
|
+
currentEndDateFact = fact
|
|
645
|
+
if currentEndDateFact is not None and currentStartDateFact is not None:
|
|
646
|
+
for asset in assetsFacts:
|
|
647
|
+
if asset.context.endDatetime - datetime.timedelta(days=1) == currentEndDateFact.xValue:
|
|
648
|
+
foundCurrentAssets = asset
|
|
649
|
+
if cast(int, asset.xValue) < 0:
|
|
650
|
+
negativeAssetFacts.append(asset)
|
|
651
|
+
for liabilitiesAndEquity in liabilitiesAndEquityFacts:
|
|
652
|
+
if liabilitiesAndEquity.context.endDatetime - datetime.timedelta(days=1) == currentEndDateFact.xValue:
|
|
653
|
+
foundCurrentLiabilitiesAndEquity = liabilitiesAndEquity
|
|
654
|
+
if cast(int, liabilitiesAndEquity.xValue) < 0:
|
|
655
|
+
negativeLiabilitiesAndEquityFacts.append(liabilitiesAndEquity)
|
|
656
|
+
foundCurrentEquity = any(
|
|
657
|
+
equity.context.endDatetime - datetime.timedelta(days=1) == currentEndDateFact.xValue
|
|
658
|
+
for equity in equityFacts
|
|
659
|
+
)
|
|
660
|
+
foundCurrentProfitLoss = any(
|
|
661
|
+
profitLoss.context.startDatetime == currentStartDateFact.xValue and
|
|
662
|
+
profitLoss.context.endDatetime - datetime.timedelta(days=1) == currentEndDateFact.xValue
|
|
663
|
+
for profitLoss in profitLossFacts
|
|
664
|
+
)
|
|
665
|
+
if foundCurrentAssets is not None and foundCurrentLiabilitiesAndEquity is not None:
|
|
666
|
+
if foundCurrentAssets.xValue != foundCurrentLiabilitiesAndEquity.xValue:
|
|
667
|
+
equalityErrorPairs.append((foundCurrentAssets, foundCurrentLiabilitiesAndEquity))
|
|
668
|
+
if foundCurrentAssets is None:
|
|
669
|
+
assetErrors.append(currentEndDateFact.xValue)
|
|
670
|
+
if foundCurrentEquity is False:
|
|
671
|
+
equityErrors.append(currentEndDateFact.xValue)
|
|
672
|
+
if foundCurrentLiabilitiesAndEquity is None:
|
|
673
|
+
liabilitiesAndEquityErrors.append(currentEndDateFact.xValue)
|
|
674
|
+
if foundCurrentProfitLoss is False:
|
|
675
|
+
profitLossErrors.append([currentStartDateFact.xValue, currentEndDateFact.xValue])
|
|
676
|
+
if precedingPeriodFound:
|
|
677
|
+
for context, facts in precedingGroupedFacts.items():
|
|
678
|
+
if len(facts) == 2:
|
|
679
|
+
for fact in facts:
|
|
680
|
+
if fact.qname == pluginData.precedingReportingPeriodStartDateQn:
|
|
681
|
+
precedingStartDateFact = fact
|
|
682
|
+
elif fact.qname == pluginData.precedingReportingPeriodEndDateQn:
|
|
683
|
+
precedingEndDateFact = fact
|
|
684
|
+
if precedingStartDateFact is not None and precedingEndDateFact is not None:
|
|
685
|
+
for asset in assetsFacts:
|
|
686
|
+
if asset.context.endDatetime - datetime.timedelta(days=1) == precedingEndDateFact.xValue:
|
|
687
|
+
foundPreviousAssets = asset
|
|
688
|
+
if cast(int, asset.xValue) < 0:
|
|
689
|
+
negativeAssetFacts.append(asset)
|
|
690
|
+
for liabilitiesAndEquity in liabilitiesAndEquityFacts:
|
|
691
|
+
if liabilitiesAndEquity.context.endDatetime - datetime.timedelta(days=1) == precedingEndDateFact.xValue:
|
|
692
|
+
foundPreviousLiabilitiesAndEquity = liabilitiesAndEquity
|
|
693
|
+
if cast(int, liabilitiesAndEquity.xValue) < 0:
|
|
694
|
+
negativeLiabilitiesAndEquityFacts.append(liabilitiesAndEquity)
|
|
695
|
+
foundPreviousEquity = any(
|
|
696
|
+
equity.context.endDatetime - datetime.timedelta(days=1) == precedingEndDateFact.xValue
|
|
697
|
+
for equity in equityFacts
|
|
698
|
+
)
|
|
699
|
+
foundPreviousProfitLoss = any(
|
|
700
|
+
profitLoss.context.startDatetime == precedingStartDateFact.xValue and
|
|
701
|
+
profitLoss.context.endDatetime - datetime.timedelta(days=1) == precedingEndDateFact.xValue
|
|
702
|
+
for profitLoss in profitLossFacts
|
|
703
|
+
)
|
|
704
|
+
if foundPreviousAssets is None:
|
|
705
|
+
assetErrors.append(precedingEndDateFact.xValue)
|
|
706
|
+
if foundPreviousEquity is False:
|
|
707
|
+
equityErrors.append(precedingEndDateFact.xValue)
|
|
708
|
+
if foundPreviousLiabilitiesAndEquity is None:
|
|
709
|
+
liabilitiesAndEquityErrors.append(precedingEndDateFact.xValue)
|
|
710
|
+
if foundPreviousProfitLoss is False:
|
|
711
|
+
profitLossErrors.append([precedingStartDateFact.xValue, precedingEndDateFact.xValue])
|
|
712
|
+
if not len(assetErrors) == 0:
|
|
713
|
+
yield Validation.error(
|
|
714
|
+
codes="DBA.FR57.Assets",
|
|
715
|
+
msg=_("Assets (fsa:Assets) must be stated and must not be negative. "
|
|
716
|
+
"There is a problem with the reporting period ending: %(periods)s"),
|
|
717
|
+
periods = ", ".join([cast(datetime.datetime, dt).strftime("%Y-%m-%d") for dt in assetErrors])
|
|
718
|
+
)
|
|
719
|
+
if not len(negativeAssetFacts) == 0:
|
|
720
|
+
for fact in negativeAssetFacts:
|
|
721
|
+
yield Validation.error(
|
|
722
|
+
codes="DBA.FR57.NegativeAssets",
|
|
723
|
+
msg=_("Assets (fsa:Assets) must not be negative. "
|
|
724
|
+
"Assets was tagged with the value: %(factValue)s"),
|
|
725
|
+
factValue = fact.effectiveValue,
|
|
726
|
+
modelObject=fact
|
|
727
|
+
)
|
|
728
|
+
if not len(equalityErrorPairs) == 0:
|
|
729
|
+
for pair in equalityErrorPairs:
|
|
730
|
+
yield Validation.error(
|
|
731
|
+
codes="DBA.FR57.Equality",
|
|
732
|
+
msg=_("The total of Assets (fsa:Assets) must be equal to the total of Liabilities and Equity (fsa:LiabilitiesAndEquity). "
|
|
733
|
+
"Assets: %(Assets)s Liabilities and Equity: %(LiabilitiesAndEquity)s"),
|
|
734
|
+
Assets=pair[0].effectiveValue,
|
|
735
|
+
LiabilitiesAndEquity=pair[1].effectiveValue,
|
|
736
|
+
modelObject=pair
|
|
737
|
+
)
|
|
738
|
+
if not len(equityErrors) == 0:
|
|
739
|
+
yield Validation.error(
|
|
740
|
+
codes="DBA.FR57.Equity",
|
|
741
|
+
msg=_("The equity (fsa:Equity) in the balance sheet must be filled in. There is a problem with the reporting period ending: %(periods)s"),
|
|
742
|
+
periods = ", ".join([cast(datetime.datetime, dt).strftime("%Y-%m-%d") for dt in equityErrors])
|
|
743
|
+
)
|
|
744
|
+
if not len(negativeLiabilitiesAndEquityFacts) == 0:
|
|
745
|
+
for fact in negativeLiabilitiesAndEquityFacts:
|
|
746
|
+
yield Validation.error(
|
|
747
|
+
codes="DBA.FR57.NegativeLiabilitiesAndEquity",
|
|
748
|
+
msg=_("Liabilities and Equity (fsa:LiabilitiesAndEquity) must not be negative. "
|
|
749
|
+
"Liabilities and Equity was tagged with the value: %(factValue)s"),
|
|
750
|
+
factValue = fact.effectiveValue,
|
|
751
|
+
modelObject=fact
|
|
752
|
+
)
|
|
753
|
+
if not len(liabilitiesAndEquityErrors) == 0:
|
|
754
|
+
yield Validation.error(
|
|
755
|
+
codes="DBA.FR57.LiabilitiesAndEquity",
|
|
756
|
+
msg=_("Liabilities and equity (fsa:LiabilitiesAndEquity) in the balance sheet must be filled in. "
|
|
757
|
+
"There is a problem with the reporting period ending: %(periods)s"),
|
|
758
|
+
periods = ", ".join([cast(datetime.datetime, dt).strftime("%Y-%m-%d") for dt in liabilitiesAndEquityErrors])
|
|
759
|
+
)
|
|
760
|
+
if not len(profitLossErrors) == 0:
|
|
761
|
+
for profitLossError in profitLossErrors:
|
|
762
|
+
yield Validation.error(
|
|
763
|
+
codes="DBA.FR57.ProfitLoss",
|
|
764
|
+
msg=_("The profit for the year (fsa:ProfitLoss) in the income statement must be filled in. "
|
|
765
|
+
"There is a problem with the reporting periods starting %(start)s and ending: %(end)s"),
|
|
766
|
+
start = profitLossError[0],
|
|
767
|
+
end = profitLossError[1]
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
@validation(
|
|
772
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
773
|
+
)
|
|
774
|
+
def rule_fr58(
|
|
775
|
+
pluginData: PluginValidationDataExtension,
|
|
776
|
+
val: ValidateXbrl,
|
|
777
|
+
*args: Any,
|
|
778
|
+
**kwargs: Any,
|
|
779
|
+
) -> Iterable[Validation]:
|
|
780
|
+
"""
|
|
781
|
+
DBA.FR58: If arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportAudit is tagged then one of the following concepts MUST also be tagged:
|
|
782
|
+
arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCriminalCodeAndFiscalTaxAndSubsidyLegislationAudit
|
|
783
|
+
arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCompaniesActOrEquivalentLegislationThatTheCompanyIsSubjectToAudit
|
|
784
|
+
arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyLegislationOnFinancialReportingIncludingAccountingAndStorageOfAccountingRecordsAudit
|
|
785
|
+
arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyOtherMattersAudit
|
|
786
|
+
|
|
787
|
+
"""
|
|
788
|
+
modelXbrl = val.modelXbrl
|
|
789
|
+
indicatorFacts = modelXbrl.factsByQname.get(pluginData.reportingResponsibilitiesOnApprovedAuditorsReportAuditQn, set())
|
|
790
|
+
if len(indicatorFacts) > 0:
|
|
791
|
+
for qname in pluginData.declarationObligationQns:
|
|
792
|
+
facts = modelXbrl.factsByQname.get(qname, set())
|
|
793
|
+
if len(facts) > 0:
|
|
794
|
+
return
|
|
795
|
+
yield Validation.warning(
|
|
796
|
+
codes='DBA.FR58',
|
|
797
|
+
msg=_("When the field 'Declaration obligations according to the declaration order ' (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportAudit) is completed, "
|
|
798
|
+
"one or more of the sub-items below must be indicated: "
|
|
799
|
+
"Declaration obligations according to the declaration order, including especially the Criminal Code as well as tax, levy and subsidy legislation (audit) (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCriminalCodeAndFiscalTaxAndSubsidyLegislationAudit)"
|
|
800
|
+
"Declaration obligations according to the declaration order, including especially the company law or similar legislation laid down for the company (audit) (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCompaniesActOrEquivalentLegislationThatTheCompanyIsSubjectToAudit)"
|
|
801
|
+
"Declaration obligations according to the declaration order, including especially the legislation on financial reporting, including on bookkeeping and storage of accounting material (audit) (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyLegislationOnFinancialReportingIncludingAccountingAndStorageOfAccountingRecordsAudit)"
|
|
802
|
+
"Declaration obligations according to the declaration order, including other matters in particular (revision (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyOtherMattersAudit)"),
|
|
803
|
+
)
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
@validation(
|
|
807
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
808
|
+
)
|
|
809
|
+
def rule_fr59(
|
|
810
|
+
pluginData: PluginValidationDataExtension,
|
|
811
|
+
val: ValidateXbrl,
|
|
812
|
+
*args: Any,
|
|
813
|
+
**kwargs: Any,
|
|
814
|
+
) -> Iterable[Validation]:
|
|
815
|
+
"""
|
|
816
|
+
DBA.FR59: When the annual report contains an audit report, which is when TypeOfAuditorAssistance = Revisionspåtegning / Auditor's report on audited financial statements, then the concept
|
|
817
|
+
arr:DescriptionOfQualificationsOfAuditedFinancialStatements must be filled in.
|
|
818
|
+
"""
|
|
819
|
+
modelXbrl = val.modelXbrl
|
|
820
|
+
noDimensionDescriptionFacts = []
|
|
821
|
+
consolidatedDescriptionFacts = []
|
|
822
|
+
descriptionFacts = modelXbrl.factsByQname.get(pluginData.descriptionOfQualificationsOfAuditedFinancialStatementsQn, set())
|
|
823
|
+
for dFact in descriptionFacts:
|
|
824
|
+
if not dFact.context.scenDimValues:
|
|
825
|
+
noDimensionDescriptionFacts.append(dFact)
|
|
826
|
+
if pluginData.consolidatedSoloDimensionQn in [dim.qname for dim in dFact.context.scenDimValues.keys()]:
|
|
827
|
+
consolidatedDescriptionFacts.append(dFact)
|
|
828
|
+
checkConsolidated = consolidatedDimensionExists(modelXbrl, pluginData.consolidatedSoloDimensionQn)
|
|
829
|
+
noDimensionIndicatorFacts = []
|
|
830
|
+
consolidatedIndicatorFacts = []
|
|
831
|
+
auditorFacts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
|
|
832
|
+
for aFact in auditorFacts:
|
|
833
|
+
if aFact.xValid >= VALID and aFact.xValue in [pluginData.auditedFinancialStatementsDanish, pluginData.auditedFinancialStatementsEnglish]:
|
|
834
|
+
if not aFact.context.scenDimValues:
|
|
835
|
+
noDimensionIndicatorFacts.append(aFact)
|
|
836
|
+
if pluginData.consolidatedSoloDimensionQn in [dim.qname for dim in aFact.context.scenDimValues.keys()]:
|
|
837
|
+
consolidatedIndicatorFacts.append(aFact)
|
|
838
|
+
if not checkConsolidated and len(noDimensionIndicatorFacts) > 0 and len(noDimensionDescriptionFacts) == 0:
|
|
839
|
+
yield Validation.error(
|
|
840
|
+
codes='DBA.FR59.noDimension',
|
|
841
|
+
msg=_("DescriptionOfQualificationsOfAuditedFinancialStatement must be tagged without dimensions when {} is tagged with the value of {}").format(
|
|
842
|
+
pluginData.typeOfAuditorAssistanceQn.localName,
|
|
843
|
+
noDimensionIndicatorFacts[0].xValue),
|
|
844
|
+
modelObject=noDimensionIndicatorFacts[0])
|
|
845
|
+
if checkConsolidated and len(consolidatedIndicatorFacts) > 0 and len(consolidatedDescriptionFacts) == 0:
|
|
846
|
+
yield Validation.error(
|
|
847
|
+
codes='DBA.FR59.consolidatedSoloDimension',
|
|
848
|
+
msg=_("DescriptionOfQualificationsOfAuditedFinancialStatement must be tagged with ConsolidatedSoloDimension when {} is tagged with the value of {}").format(
|
|
849
|
+
pluginData.typeOfAuditorAssistanceQn.localName,
|
|
850
|
+
consolidatedIndicatorFacts[0].xValue),
|
|
851
|
+
modelObject=consolidatedIndicatorFacts[0])
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
@validation(
|
|
855
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
856
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
857
|
+
)
|
|
858
|
+
def rule_fr63(
|
|
859
|
+
pluginData: PluginValidationDataExtension,
|
|
860
|
+
val: ValidateXbrl,
|
|
861
|
+
*args: Any,
|
|
862
|
+
**kwargs: Any,
|
|
863
|
+
) -> Iterable[Validation]:
|
|
864
|
+
"""
|
|
865
|
+
DBA.FR63: Items in the balance sheet must be less than or equal to the balance sheet total. Assets must be
|
|
866
|
+
less than or equal to the balance sheet total. Applies to both the year's figures and comparative figures.
|
|
867
|
+
"""
|
|
868
|
+
modelXbrl = val.modelXbrl
|
|
869
|
+
asset_facts = modelXbrl.factsByQname.get(pluginData.assetsQn, set())
|
|
870
|
+
for asset_fact in asset_facts:
|
|
871
|
+
if asset_fact.xValid >= VALID and isinstance(asset_fact.xValue, decimal.Decimal):
|
|
872
|
+
concepts_in_error = []
|
|
873
|
+
facts_in_error = []
|
|
874
|
+
for balance_sheet_qn in pluginData.balanceSheetQnLessThanOrEqualToAssets:
|
|
875
|
+
balance_sheet_qn_facts = modelXbrl.factsByQname.get(balance_sheet_qn, set())
|
|
876
|
+
for balance_sheet_qn_fact in balance_sheet_qn_facts:
|
|
877
|
+
if (balance_sheet_qn_fact.xValid >= VALID and
|
|
878
|
+
isinstance(balance_sheet_qn_fact.xValue, decimal.Decimal) and
|
|
879
|
+
asset_fact.contextID == balance_sheet_qn_fact.contextID and
|
|
880
|
+
asset_fact.xValue < balance_sheet_qn_fact.xValue):
|
|
881
|
+
concepts_in_error.append(balance_sheet_qn.localName)
|
|
882
|
+
facts_in_error.append(balance_sheet_qn_fact)
|
|
883
|
+
if len(facts_in_error) > 0:
|
|
884
|
+
yield Validation.error(
|
|
885
|
+
codes='DBA.FR63',
|
|
886
|
+
msg=_("The annual report contains items in the balance sheet (year's figures or comparison "
|
|
887
|
+
"figures) which are greater than the balance sheet total(Assets). The following "
|
|
888
|
+
"fields do not comply: {}").format(concepts_in_error),
|
|
889
|
+
modelObject=facts_in_error
|
|
890
|
+
)
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
@validation(
|
|
894
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
895
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
896
|
+
)
|
|
897
|
+
def rule_fr71(
|
|
898
|
+
pluginData: PluginValidationDataExtension,
|
|
899
|
+
val: ValidateXbrl,
|
|
900
|
+
*args: Any,
|
|
901
|
+
**kwargs: Any,
|
|
902
|
+
) -> Iterable[Validation]:
|
|
903
|
+
"""
|
|
904
|
+
DBA.FR71: The accounts must not contain negative personnel costs
|
|
905
|
+
|
|
906
|
+
Costs must be reported as positive numbers in the XBRL file. It indicates that there is an error in the setup of the XBRL file.
|
|
907
|
+
The following elements are checked:
|
|
908
|
+
• Personnel costs (fsa:EmployeeBenefitsExpense),
|
|
909
|
+
• Salaries (fsa:WagesAndSalaries)
|
|
910
|
+
• Pensions (fsa:PostemploymentBenefitExpense)
|
|
911
|
+
• Other personnel costs (fsa:OtherEmployeeExpense)
|
|
912
|
+
|
|
913
|
+
Both on the year's figures and comparative figures."
|
|
914
|
+
"""
|
|
915
|
+
modelXbrl = val.modelXbrl
|
|
916
|
+
facts_in_error = []
|
|
917
|
+
for cost_qn in [
|
|
918
|
+
pluginData.employeeBenefitsExpenseQn,
|
|
919
|
+
pluginData.wagesAndSalariesQn,
|
|
920
|
+
pluginData.postemploymentBenefitExpenseQn,
|
|
921
|
+
pluginData.otherEmployeeExpenseQn
|
|
922
|
+
]:
|
|
923
|
+
facts = modelXbrl.factsByQname.get(cost_qn, set())
|
|
924
|
+
for fact in facts:
|
|
925
|
+
if fact.xValid >= VALID and isinstance(fact.xValue, decimal.Decimal) and fact.xValue < 0:
|
|
926
|
+
facts_in_error.append(fact)
|
|
927
|
+
if len(facts_in_error) > 0:
|
|
928
|
+
yield Validation.warning(
|
|
929
|
+
codes="DBA.FR71",
|
|
930
|
+
msg=_("Costs must be reported as positive numbers in the XBRL file"),
|
|
931
|
+
modelObject=facts_in_error
|
|
932
|
+
)
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
@validation(
|
|
936
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
937
|
+
)
|
|
938
|
+
def rule_fr72(
|
|
939
|
+
pluginData: PluginValidationDataExtension,
|
|
940
|
+
val: ValidateXbrl,
|
|
941
|
+
*args: Any,
|
|
942
|
+
**kwargs: Any,
|
|
943
|
+
) -> Iterable[Validation]:
|
|
944
|
+
"""
|
|
945
|
+
DBA.FR72: If the value of arr:TypeOfBasisForModifiedOpinionOnFinancialStatementsReview is set to one of the following:
|
|
946
|
+
Grundlag for konklusion med forbehold // Basis for Qualified Opinion
|
|
947
|
+
Grundlag for afkræftende konklusion // Basis for Adverse Opinion
|
|
948
|
+
Grundlag for manglende konklusion // Basis for Disclaimer of Opinion
|
|
949
|
+
then arr:DescriptionsOfQualificationsOfReviewedFinancialStatements must be tagged.
|
|
950
|
+
"""
|
|
951
|
+
modelXbrl = val.modelXbrl
|
|
952
|
+
review_facts = modelXbrl.factsByQname.get(pluginData.typeOfBasisForModifiedOpinionOnFinancialStatementsReviewQn, set())
|
|
953
|
+
for review_fact in review_facts:
|
|
954
|
+
if review_fact.xValid >= VALID and review_fact.xValue in [
|
|
955
|
+
pluginData.basisForAdverseOpinionDanish,
|
|
956
|
+
pluginData.basisForAdverseOpinionEnglish,
|
|
957
|
+
pluginData.basisForDisclaimerOpinionDanish,
|
|
958
|
+
pluginData.basisForDisclaimerOpinionEnglish,
|
|
959
|
+
pluginData.basisForQualifiedOpinionDanish,
|
|
960
|
+
pluginData.basisForQualifiedOpinionEnglish,
|
|
961
|
+
]:
|
|
962
|
+
description_facts = modelXbrl.factsByQname.get(pluginData.descriptionsOfQualificationsOfReviewedFinancialStatementsQn, set())
|
|
963
|
+
if len(description_facts) == 0:
|
|
964
|
+
yield Validation.warning(
|
|
965
|
+
codes='DBA.FR72',
|
|
966
|
+
msg=_("DescriptionsOfQualificationsOfReviewedFinancialStatements must be tagged when {} is tagged with the value of {}").format(
|
|
967
|
+
pluginData.typeOfBasisForModifiedOpinionOnFinancialStatementsReviewQn.localName,
|
|
968
|
+
review_fact.xValue
|
|
969
|
+
),
|
|
970
|
+
modelObject=review_fact
|
|
971
|
+
)
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
@validation(
|
|
975
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
976
|
+
)
|
|
977
|
+
def rule_fr73(
|
|
978
|
+
pluginData: PluginValidationDataExtension,
|
|
979
|
+
val: ValidateXbrl,
|
|
980
|
+
*args: Any,
|
|
981
|
+
**kwargs: Any,
|
|
982
|
+
) -> Iterable[Validation]:
|
|
983
|
+
"""
|
|
984
|
+
DBA.FR73: If arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsExtendedReview is tagged then one of the following concepts MUST also be tagged:
|
|
985
|
+
arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCriminalCodeAndFiscalTaxAndSubsidyLegislationExtendedReview
|
|
986
|
+
arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCompaniesActOrEquivalentLegislationThatTheCompanyIsSubjectToExtendedReview
|
|
987
|
+
arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyLegislationOnFinancialReportingInApplication
|
|
988
|
+
"""
|
|
989
|
+
modelXbrl = val.modelXbrl
|
|
990
|
+
indicatorFacts = modelXbrl.factsByQname.get(pluginData.reportingResponsibilitiesOnApprovedAuditorsReportsExtendedReviewQn, set())
|
|
991
|
+
if len(indicatorFacts) > 0:
|
|
992
|
+
for qname in pluginData.reportingObligationQns:
|
|
993
|
+
facts = modelXbrl.factsByQname.get(qname, set())
|
|
994
|
+
if len(facts) > 0:
|
|
995
|
+
return
|
|
996
|
+
yield Validation.warning(
|
|
997
|
+
codes='DBA.FR73',
|
|
998
|
+
msg=_("When the field ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsExtendedReview is completed "
|
|
999
|
+
"one or more of the sub-items below must be indicated: "
|
|
1000
|
+
"ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCriminalCodeAndFiscalTaxAndSubsidyLegislationExtendedReview "
|
|
1001
|
+
"ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCompaniesActOrEquivalentLegislationThatTheCompanyIsSubjectToExtendedReview "
|
|
1002
|
+
"ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyLegislationOnFinancialReportingInApplication."),
|
|
1003
|
+
)
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
@validation(
|
|
1008
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1009
|
+
)
|
|
1010
|
+
def rule_fr74(
|
|
1011
|
+
pluginData: PluginValidationDataExtension,
|
|
1012
|
+
val: ValidateXbrl,
|
|
1013
|
+
*args: Any,
|
|
1014
|
+
**kwargs: Any,
|
|
1015
|
+
) -> Iterable[Validation]:
|
|
1016
|
+
"""
|
|
1017
|
+
DBA.FR74a:Provisions [hierarchy:fsa:Provisions] and underlying fields must each be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity).
|
|
1018
|
+
DBA.FR74b: Liabilities (fsa:LiabilitiesOtherThanProvisions) must be less than or equal to total assets (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity).
|
|
1019
|
+
"""
|
|
1020
|
+
groupedFacts = getFactsGroupedByContextId(val.modelXbrl, pluginData.equityQn, pluginData.liabilitiesAndEquityQn, pluginData.provisionsQn, pluginData.liabilitiesOtherThanProvisionsQn)
|
|
1021
|
+
for contextID, facts in groupedFacts.items():
|
|
1022
|
+
equityFact = None
|
|
1023
|
+
liabilityFact = None
|
|
1024
|
+
liabilityOtherFact = None
|
|
1025
|
+
provisionFact = None
|
|
1026
|
+
for fact in facts:
|
|
1027
|
+
if fact.qname == pluginData.equityQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
|
|
1028
|
+
equityFact = fact
|
|
1029
|
+
elif fact.qname == pluginData.liabilitiesQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
|
|
1030
|
+
liabilityFact = fact
|
|
1031
|
+
elif fact.qname == pluginData.provisionsQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
|
|
1032
|
+
provisionFact = fact
|
|
1033
|
+
elif fact.qname == pluginData.liabilitiesOtherThanProvisionsQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
|
|
1034
|
+
liabilityOtherFact = fact
|
|
1035
|
+
if equityFact is not None and liabilityFact is not None and provisionFact is not None and equityFact.xValid >= VALID and liabilityFact.xValid >= VALID and provisionFact.xValid >= VALID:
|
|
1036
|
+
if not cast(decimal.Decimal, liabilityFact.xValue) - cast(decimal.Decimal, equityFact.xValue) >= cast(decimal.Decimal, provisionFact.xValue) - ROUNDING_MARGIN:
|
|
1037
|
+
yield Validation.error(
|
|
1038
|
+
codes="DBA.FR74a",
|
|
1039
|
+
msg=_("Provisions (fsa:Provisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity). "
|
|
1040
|
+
"LiabilitiesAndEquity: %(liabilities)s, Equity: %(equity)s, Provisions: %(provisions)s"),
|
|
1041
|
+
equity=equityFact.effectiveValue,
|
|
1042
|
+
liabilities=liabilityFact.effectiveValue,
|
|
1043
|
+
provisions=provisionFact.effectiveValue,
|
|
1044
|
+
modelObject=[equityFact, liabilityFact, provisionFact]
|
|
1045
|
+
)
|
|
1046
|
+
if equityFact is not None and liabilityOtherFact is not None and liabilityFact is not None and equityFact.xValid >= VALID and liabilityFact.xValid >= VALID and liabilityOtherFact.xValid >= VALID:
|
|
1047
|
+
if not cast(decimal.Decimal, liabilityFact.xValue) - cast(decimal.Decimal, equityFact.xValue) >= cast(decimal.Decimal, liabilityOtherFact.xValue) - ROUNDING_MARGIN:
|
|
1048
|
+
yield Validation.error(
|
|
1049
|
+
codes="DBA.FR74b",
|
|
1050
|
+
msg=_("Liabilities (fsa:LiabilitiesOtherThanProvisions) must be less than or equal to total assets (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity). "
|
|
1051
|
+
"LiabilitiesAndEquity: %(liabilities)s, Equity: %(equity)s, LiabilitiesOtherThanProvisions: %(liabilityOther)s"),
|
|
1052
|
+
equity=equityFact.effectiveValue,
|
|
1053
|
+
liabilityOther=liabilityOtherFact.effectiveValue,
|
|
1054
|
+
liabilities=liabilityFact.effectiveValue,
|
|
1055
|
+
modelObject=[equityFact, liabilityFact, liabilityOtherFact]
|
|
1056
|
+
)
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
@validation(
|
|
1060
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1061
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
1062
|
+
)
|
|
1063
|
+
def rule_fr75(
|
|
1064
|
+
pluginData: PluginValidationDataExtension,
|
|
1065
|
+
val: ValidateXbrl,
|
|
1066
|
+
*args: Any,
|
|
1067
|
+
**kwargs: Any,
|
|
1068
|
+
) -> Iterable[Validation]:
|
|
1069
|
+
"""
|
|
1070
|
+
DBA.FR75: The company must provide information on the number of employees. The rule is activated if personnel costs (fsa:EmployeeBenefitsExpense) or salaries (fsa:WagesAndSalaries) are greater
|
|
1071
|
+
than DKK 200,000, and no number of employees (fsa:AverageNumberOfEmployees) has been specified.
|
|
1072
|
+
"""
|
|
1073
|
+
groupedFacts = getFactsGroupedByContextId(val.modelXbrl, pluginData.employeeBenefitsExpenseQn, pluginData.wagesAndSalariesQn, pluginData.averageNumberOfEmployeesQn)
|
|
1074
|
+
for contextID, facts in groupedFacts.items():
|
|
1075
|
+
benefitsFact = None
|
|
1076
|
+
wagesFact = None
|
|
1077
|
+
employeesFact = None
|
|
1078
|
+
for fact in facts:
|
|
1079
|
+
if fact.qname == pluginData.employeeBenefitsExpenseQn and fact.unit.id.upper() == DANISH_CURRENCY_ID and fact.xValid >= VALID and cast(decimal.Decimal, fact.xValue) >= PERSONNEL_EXPENSE_THRESHOLD:
|
|
1080
|
+
benefitsFact = fact
|
|
1081
|
+
elif fact.qname == pluginData.wagesAndSalariesQn and fact.unit.id.upper() == DANISH_CURRENCY_ID and fact.xValid >= VALID and cast(decimal.Decimal, fact.xValue) >= PERSONNEL_EXPENSE_THRESHOLD:
|
|
1082
|
+
wagesFact = fact
|
|
1083
|
+
elif fact.qname == pluginData.averageNumberOfEmployeesQn and fact.xValid >= VALID and cast(decimal.Decimal, fact.xValue) > 0:
|
|
1084
|
+
employeesFact = fact
|
|
1085
|
+
if (benefitsFact is not None or wagesFact is not None) and employeesFact is None:
|
|
1086
|
+
yield Validation.error(
|
|
1087
|
+
codes="DBA.FR75",
|
|
1088
|
+
msg=_("The company must provide information on the number of employees. The rule is activated if personnel costs (fsa:EmployeeBenefitsExpense) "
|
|
1089
|
+
"or salaries (fsa:WagesAndSalaries) are greater than DKK 200,000, and no number of employees (fsa:AverageNumberOfEmployees) has been specified."),
|
|
1090
|
+
modelObject=[benefitsFact, wagesFact]
|
|
1091
|
+
)
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
@validation(
|
|
1095
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1096
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
1097
|
+
)
|
|
1098
|
+
def rule_fr77(
|
|
1099
|
+
pluginData: PluginValidationDataExtension,
|
|
1100
|
+
val: ValidateXbrl,
|
|
1101
|
+
*args: Any,
|
|
1102
|
+
**kwargs: Any,
|
|
1103
|
+
) -> Iterable[Validation]:
|
|
1104
|
+
"""
|
|
1105
|
+
DBA.FR77b: Long-term liabilities (fsa:LongtermLiabilitiesOtherThanProvisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity).
|
|
1106
|
+
DBA.FR77b: Short-term liabilities (fsa:ShorttermLiabilitiesOtherThanProvisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity).
|
|
1107
|
+
"""
|
|
1108
|
+
groupedFacts = getFactsGroupedByContextId(val.modelXbrl, pluginData.equityQn, pluginData.liabilitiesAndEquityQn, pluginData.longtermLiabilitiesOtherThanProvisionsQn, pluginData.shorttermLiabilitiesOtherThanProvisionsQn)
|
|
1109
|
+
for contextID, facts in groupedFacts.items():
|
|
1110
|
+
equityFact = None
|
|
1111
|
+
liabilityFact = None
|
|
1112
|
+
longLiabilityFact = None
|
|
1113
|
+
shortLiabilityFact = None
|
|
1114
|
+
for fact in facts:
|
|
1115
|
+
if fact.qname == pluginData.equityQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
|
|
1116
|
+
equityFact = fact
|
|
1117
|
+
elif fact.qname == pluginData.liabilitiesQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
|
|
1118
|
+
liabilityFact = fact
|
|
1119
|
+
elif fact.qname == pluginData.longtermLiabilitiesOtherThanProvisionsQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
|
|
1120
|
+
longLiabilityFact = fact
|
|
1121
|
+
elif fact.qname == pluginData.shorttermLiabilitiesOtherThanProvisionsQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
|
|
1122
|
+
shortLiabilityFact = fact
|
|
1123
|
+
if equityFact is not None and liabilityFact is not None and longLiabilityFact is not None and equityFact.xValid >= VALID and liabilityFact.xValid >= VALID and longLiabilityFact.xValid >= VALID:
|
|
1124
|
+
if not cast(decimal.Decimal, liabilityFact.xValue) - cast(decimal.Decimal, equityFact.xValue) >= cast(decimal.Decimal, longLiabilityFact.xValue) - ROUNDING_MARGIN:
|
|
1125
|
+
yield Validation.error(
|
|
1126
|
+
codes="DBA.FR77a",
|
|
1127
|
+
msg=_("Long-term liabilities (fsa:LongtermLiabilitiesOtherThanProvisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity). "
|
|
1128
|
+
"LiabilitiesAndEquity: %(liabilities)s, Equity: %(equity)s, LongtermLiabilitiesOtherThanProvisions: %(longLiabilities)s"),
|
|
1129
|
+
equity=equityFact.effectiveValue,
|
|
1130
|
+
liabilities=liabilityFact.effectiveValue,
|
|
1131
|
+
longLiabilities=longLiabilityFact.effectiveValue,
|
|
1132
|
+
modelObject=[equityFact, liabilityFact, longLiabilityFact]
|
|
1133
|
+
)
|
|
1134
|
+
if equityFact is not None and liabilityFact is not None and shortLiabilityFact is not None and equityFact.xValid >= VALID and liabilityFact.xValid >= VALID and shortLiabilityFact.xValid >= VALID:
|
|
1135
|
+
if not cast(decimal.Decimal, liabilityFact.xValue) - cast(decimal.Decimal, equityFact.xValue) >= cast(decimal.Decimal, shortLiabilityFact.xValue) - ROUNDING_MARGIN:
|
|
1136
|
+
yield Validation.error(
|
|
1137
|
+
codes="DBA.FR77b",
|
|
1138
|
+
msg=_("Short-term liabilities (fsa:ShorttermLiabilitiesOtherThanProvisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity). "
|
|
1139
|
+
"LiabilitiesAndEquity: %(liabilities)s, Equity: %(equity)s, ShorttermLiabilitiesOtherThanProvisions: %(shortLiabilities)s"),
|
|
1140
|
+
equity=equityFact.effectiveValue,
|
|
1141
|
+
liabilities=liabilityFact.effectiveValue,
|
|
1142
|
+
shortLiabilities=shortLiabilityFact.effectiveValue,
|
|
1143
|
+
modelObject=[equityFact, liabilityFact, shortLiabilityFact]
|
|
1144
|
+
)
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
@validation(
|
|
1148
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1149
|
+
)
|
|
1150
|
+
def rule_fr81(
|
|
1151
|
+
pluginData: PluginValidationDataExtension,
|
|
1152
|
+
val: ValidateXbrl,
|
|
1153
|
+
*args: Any,
|
|
1154
|
+
**kwargs: Any,
|
|
1155
|
+
) -> Iterable[Validation]:
|
|
1156
|
+
"""
|
|
1157
|
+
DBA.FR81: The language used must be stated. There must be at least one fact with either the Danish
|
|
1158
|
+
(`da`) or English (`en`) `lang` attribute in the digital file (the XBRL file or the IXBRL file).
|
|
1159
|
+
|
|
1160
|
+
Implementation: Check all facts for at least one `lang` attribute that must be either `da` or `en`.
|
|
1161
|
+
"""
|
|
1162
|
+
has_valid_lang = any(fact.xmlLang in {'da', 'en'} for fact in val.modelXbrl.facts)
|
|
1163
|
+
if not has_valid_lang:
|
|
1164
|
+
yield Validation.error(
|
|
1165
|
+
codes="DBA.FR81",
|
|
1166
|
+
msg=_("The digital annual report does not contain a technical indication of the language used. There "
|
|
1167
|
+
"must be at least one fact, with either the Danish ('da') or English ('en') language attribute."),
|
|
1168
|
+
modelObject=[val.modelXbrl.modelDocument]
|
|
1169
|
+
)
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
@validation(
|
|
1173
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1174
|
+
disclosureSystems=MULTI_TARGET_DISCLOSURE_SYSTEMS,
|
|
1175
|
+
)
|
|
1176
|
+
def rule_fr82(
|
|
1177
|
+
pluginData: PluginValidationDataExtension,
|
|
1178
|
+
val: ValidateXbrl,
|
|
1179
|
+
*args: Any,
|
|
1180
|
+
**kwargs: Any,
|
|
1181
|
+
) -> Iterable[Validation]:
|
|
1182
|
+
"""
|
|
1183
|
+
DBA.FR82: This control blocks reporting in XBRL and thus only allows reporting with inlineXBRL for DK ESEF.
|
|
1184
|
+
"""
|
|
1185
|
+
if (val.modelXbrl.modelDocument is not None and
|
|
1186
|
+
val.modelXbrl.modelDocument.type not in [ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INLINEXBRLDOCUMENTSET]):
|
|
1187
|
+
yield Validation.error(
|
|
1188
|
+
codes="DBA.FR82",
|
|
1189
|
+
msg=_("The digital annual report must be reported in inlineXBRL for DK ESEF."),
|
|
1190
|
+
modelObject=[val.modelXbrl.modelDocument]
|
|
1191
|
+
)
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
@validation(
|
|
1195
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1196
|
+
disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
|
|
1197
|
+
)
|
|
1198
|
+
def rule_fr83(
|
|
1199
|
+
pluginData: PluginValidationDataExtension,
|
|
1200
|
+
val: ValidateXbrl,
|
|
1201
|
+
*args: Any,
|
|
1202
|
+
**kwargs: Any,
|
|
1203
|
+
) -> Iterable[Validation]:
|
|
1204
|
+
"""
|
|
1205
|
+
DBA.FR83: This control blocks reporting in XBRL and thus only allows reporting with inlineXBRL for DK GAAP.
|
|
1206
|
+
"""
|
|
1207
|
+
if (val.modelXbrl.modelDocument is not None and
|
|
1208
|
+
val.modelXbrl.modelDocument.type not in [ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INLINEXBRLDOCUMENTSET]):
|
|
1209
|
+
yield Validation.error(
|
|
1210
|
+
codes="DBA.FR83",
|
|
1211
|
+
msg=_("The digital annual report must be reported in inlineXBRL for DK GAAP."),
|
|
1212
|
+
modelObject=[val.modelXbrl.modelDocument]
|
|
1213
|
+
)
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
@validation(
|
|
1217
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1218
|
+
)
|
|
1219
|
+
def rule_fr87(
|
|
1220
|
+
pluginData: PluginValidationDataExtension,
|
|
1221
|
+
val: ValidateXbrl,
|
|
1222
|
+
*args: Any,
|
|
1223
|
+
**kwargs: Any,
|
|
1224
|
+
) -> Iterable[Validation]:
|
|
1225
|
+
"""
|
|
1226
|
+
DBA.FR87: InlineXBRL must not link to external CSS. The IXBRL file must have all CSS inline.
|
|
1227
|
+
"""
|
|
1228
|
+
modelXbrl = val.modelXbrl
|
|
1229
|
+
_xhtmlNs = "{{{}}}".format(xhtml)
|
|
1230
|
+
_xhtmlNsLen = len(_xhtmlNs)
|
|
1231
|
+
if hasattr(modelXbrl, "ixdsHtmlElements"):
|
|
1232
|
+
for ixdsHtmlRootElt in modelXbrl.ixdsHtmlElements: # ix root elements for all ix docs in IXDS
|
|
1233
|
+
ixNStag = ixdsHtmlRootElt.modelDocument.ixNStag
|
|
1234
|
+
ixTags = set(ixNStag + ln for ln in ("nonNumeric", "nonFraction", "references", "relationship"))
|
|
1235
|
+
ixTargets = set()
|
|
1236
|
+
for ixdsHtmlRootElt in modelXbrl.ixdsHtmlElements:
|
|
1237
|
+
for elt in ixdsHtmlRootElt.iter():
|
|
1238
|
+
eltTag = elt.tag
|
|
1239
|
+
if eltTag in ixTags:
|
|
1240
|
+
ixTargets.add( elt.get("target") )
|
|
1241
|
+
else:
|
|
1242
|
+
if eltTag.startswith(_xhtmlNs):
|
|
1243
|
+
eltTag = eltTag[_xhtmlNsLen:]
|
|
1244
|
+
if eltTag == "link" and elt.get("type") == "text/css":
|
|
1245
|
+
yield Validation.error(
|
|
1246
|
+
codes='DBA.FR87',
|
|
1247
|
+
msg=_("CSS must be embedded in the inline XBRL document. The document contains a link to an external CSS file."),
|
|
1248
|
+
modelObject=elt,
|
|
1249
|
+
)
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
@validation(
|
|
1253
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1254
|
+
)
|
|
1255
|
+
def rule_fr89(
|
|
1256
|
+
pluginData: PluginValidationDataExtension,
|
|
1257
|
+
val: ValidateXbrl,
|
|
1258
|
+
*args: Any,
|
|
1259
|
+
**kwargs: Any,
|
|
1260
|
+
) -> Iterable[Validation]:
|
|
1261
|
+
"""
|
|
1262
|
+
DBA.FR89: If ClassOfReportingEntity is one of the following values:
|
|
1263
|
+
|
|
1264
|
+
Regnskabsklasse C, mellemstor virksomhed // Reporting class C, medium-size enterprise
|
|
1265
|
+
Regnskabsklasse C, stor virksomhed // Reporting class C, large enterprise
|
|
1266
|
+
Regnskabsklasse D // Reporting class D
|
|
1267
|
+
Then TypeOfAuditorAssistance should be: Revisionspåtegning // Auditor's report on audited financial statements
|
|
1268
|
+
"""
|
|
1269
|
+
if pluginData.isAnnualReport(val.modelXbrl):
|
|
1270
|
+
auditorFacts = val.modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
|
|
1271
|
+
for auditorFact in auditorFacts:
|
|
1272
|
+
if auditorFact.xValid >= VALID and auditorFact.xValue in [
|
|
1273
|
+
pluginData.auditedFinancialStatementsDanish,
|
|
1274
|
+
pluginData.auditedFinancialStatementsEnglish
|
|
1275
|
+
]:
|
|
1276
|
+
return
|
|
1277
|
+
classFacts = []
|
|
1278
|
+
facts = val.modelXbrl.factsByQname.get(pluginData.classOfReportingEntityQn, set())
|
|
1279
|
+
for fact in facts:
|
|
1280
|
+
if fact.xValid >= VALID and fact.xValue in [
|
|
1281
|
+
pluginData.reportingClassCLargeDanish,
|
|
1282
|
+
pluginData.reportingClassCLargeEnglish,
|
|
1283
|
+
pluginData.reportingClassCMediumDanish,
|
|
1284
|
+
pluginData.reportingClassCMediumEnglish,
|
|
1285
|
+
pluginData.reportingClassDDanish,
|
|
1286
|
+
pluginData.reportingClassDEnglish
|
|
1287
|
+
]:
|
|
1288
|
+
classFacts.append(fact)
|
|
1289
|
+
if len(classFacts) > 0:
|
|
1290
|
+
yield Validation.error(
|
|
1291
|
+
codes='DBA.FR89',
|
|
1292
|
+
msg=_("TypeOfAuditorAssistance should be {} or {} when {} is tagged with the value of {}.").format(
|
|
1293
|
+
pluginData.auditedFinancialStatementsDanish,
|
|
1294
|
+
pluginData.auditedFinancialStatementsEnglish,
|
|
1295
|
+
pluginData.classOfReportingEntityQn.localName,
|
|
1296
|
+
classFacts[0].xValue
|
|
1297
|
+
),
|
|
1298
|
+
modelObject=classFacts[0]
|
|
1299
|
+
)
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
@validation(
|
|
1303
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1304
|
+
)
|
|
1305
|
+
def rule_fr91(
|
|
1306
|
+
pluginData: PluginValidationDataExtension,
|
|
1307
|
+
val: ValidateXbrl,
|
|
1308
|
+
*args: Any,
|
|
1309
|
+
**kwargs: Any,
|
|
1310
|
+
) -> Iterable[Validation]:
|
|
1311
|
+
"""
|
|
1312
|
+
DBA.FR91: If the annual report contains information about both the general meeting date
|
|
1313
|
+
(gsd:DateOfGeneralMeeting) and the annual accounts meeting date (gsd:DateOfApprovalOfAnnualReport), the values must be the same.
|
|
1314
|
+
"""
|
|
1315
|
+
if pluginData.isAnnualReport(val.modelXbrl):
|
|
1316
|
+
approvalOfReportFact = None
|
|
1317
|
+
generalMeetingFact = None
|
|
1318
|
+
approvalFacts = (val.modelXbrl.factsByQname.get(pluginData.dateOfApprovalOfAnnualReportQn, set()))
|
|
1319
|
+
if len(approvalFacts) > 0:
|
|
1320
|
+
approvalOfReportFact = next(iter(approvalFacts), None)
|
|
1321
|
+
meetingFacts = val.modelXbrl.factsByQname.get(pluginData.dateOfGeneralMeetingQn, set())
|
|
1322
|
+
if len(meetingFacts) > 0:
|
|
1323
|
+
generalMeetingFact = next(iter(meetingFacts), None)
|
|
1324
|
+
if generalMeetingFact is not None and generalMeetingFact.xValid >= VALID and approvalOfReportFact is not None and approvalOfReportFact.xValid >= VALID and generalMeetingFact.xValue != approvalOfReportFact.xValue:
|
|
1325
|
+
yield Validation.error(
|
|
1326
|
+
codes='DBA.FR91',
|
|
1327
|
+
msg=_("The annual report contains information about both the general meeting date (gsd:DateOfGeneralMeeting) and the annual accounts meeting date (gsd:DateOfApprovalOfAnnualReport), the values must be the same."),
|
|
1328
|
+
modelObject=[generalMeetingFact, approvalOfReportFact]
|
|
1329
|
+
)
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
@validation(
|
|
1333
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1334
|
+
)
|
|
1335
|
+
def rule_fr92(
|
|
1336
|
+
pluginData: PluginValidationDataExtension,
|
|
1337
|
+
val: ValidateXbrl,
|
|
1338
|
+
*args: Any,
|
|
1339
|
+
**kwargs: Any,
|
|
1340
|
+
) -> Iterable[Validation]:
|
|
1341
|
+
"""
|
|
1342
|
+
DBA.FR92: Information is missing on the auditor's signature date.
|
|
1343
|
+
|
|
1344
|
+
The auditor's signature date must be provided when (fsa:TypeOfAuditorAssistance) is
|
|
1345
|
+
tagged with one of the following values:
|
|
1346
|
+
- (Revisionspåtegning) / (Auditor's report on audited financial statements)
|
|
1347
|
+
- (Erklæring om udvidet gennemgang) / (Auditor's report on extended review)
|
|
1348
|
+
- (Den uafhængige revisors erklæringer (review)) / (The independent auditor's reports (Review))
|
|
1349
|
+
- (Andre erklæringer med sikkerhed) / (The independent auditor's reports (Other assurance Reports))
|
|
1350
|
+
- (Andre erklæringer uden sikkerhed) / (Auditor's reports (Other non-assurance reports))
|
|
1351
|
+
"""
|
|
1352
|
+
modelXbrl = val.modelXbrl
|
|
1353
|
+
facts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
|
|
1354
|
+
for fact in facts:
|
|
1355
|
+
if fact.xValid >= VALID:
|
|
1356
|
+
if fact.xValue in [
|
|
1357
|
+
pluginData.auditedFinancialStatementsDanish,
|
|
1358
|
+
pluginData.auditedFinancialStatementsEnglish,
|
|
1359
|
+
pluginData.auditedExtendedReviewDanish,
|
|
1360
|
+
pluginData.auditedExtendedReviewEnglish,
|
|
1361
|
+
pluginData.independentAuditorsReportDanish,
|
|
1362
|
+
pluginData.independentAuditorsReportEnglish,
|
|
1363
|
+
pluginData.auditedAssuranceReportsDanish,
|
|
1364
|
+
pluginData.auditedAssuranceReportsEnglish,
|
|
1365
|
+
pluginData.auditedNonAssuranceReportsDanish,
|
|
1366
|
+
pluginData.auditedNonAssuranceReportsEnglish,
|
|
1367
|
+
]:
|
|
1368
|
+
signature_facts = modelXbrl.factsByQname.get(pluginData.signatureOfAuditorsDateQn, set())
|
|
1369
|
+
if len(signature_facts) == 0:
|
|
1370
|
+
yield Validation.error(
|
|
1371
|
+
codes='DBA.FR92',
|
|
1372
|
+
msg=_("SignatureOfAuditorsDate must be tagged when {} is tagged with the value of {}").format(
|
|
1373
|
+
pluginData.typeOfAuditorAssistanceQn.localName,
|
|
1374
|
+
fact.xValue
|
|
1375
|
+
),
|
|
1376
|
+
modelObject=fact
|
|
1377
|
+
)
|