arelle-release 2.37.21__py3-none-any.whl → 2.37.23__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.
Potentially problematic release.
This version of arelle-release might be problematic. Click here for more details.
- arelle/ModelRelationshipSet.py +3 -0
- arelle/ValidateDuplicateFacts.py +13 -7
- arelle/XbrlConst.py +3 -0
- arelle/_version.py +2 -2
- arelle/api/Session.py +88 -58
- arelle/plugin/validate/DBA/rules/fr.py +10 -10
- arelle/plugin/validate/DBA/rules/th.py +1 -1
- arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +21 -20
- arelle/plugin/validate/NL/DisclosureSystems.py +14 -0
- arelle/plugin/validate/NL/PluginValidationDataExtension.py +167 -3
- arelle/plugin/validate/NL/ValidationPluginExtension.py +10 -1
- arelle/plugin/validate/NL/resources/config.xml +12 -1
- arelle/plugin/validate/NL/rules/fr_kvk.py +1 -1
- arelle/plugin/validate/NL/rules/nl_kvk.py +680 -155
- arelle/utils/validate/DetectScriptsInXhtml.py +1 -4
- arelle/utils/validate/ESEFImage.py +274 -0
- {arelle_release-2.37.21.dist-info → arelle_release-2.37.23.dist-info}/METADATA +1 -1
- {arelle_release-2.37.21.dist-info → arelle_release-2.37.23.dist-info}/RECORD +27 -26
- tests/integration_tests/validation/conformance_suite_configs.py +2 -0
- tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py +30 -43
- tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024_gaap_other.py +244 -0
- tests/integration_tests/validation/discover_tests.py +2 -2
- tests/unit_tests/arelle/plugin/validate/ESEF/ESEF_Current/test_validate_css_url.py +10 -2
- arelle/plugin/validate/ESEF/ESEF_Current/Image.py +0 -213
- {arelle_release-2.37.21.dist-info → arelle_release-2.37.23.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.21.dist-info → arelle_release-2.37.23.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.21.dist-info → arelle_release-2.37.23.dist-info}/licenses/LICENSE.md +0 -0
- {arelle_release-2.37.21.dist-info → arelle_release-2.37.23.dist-info}/top_level.txt +0 -0
|
@@ -7,7 +7,7 @@ from collections import defaultdict
|
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
from functools import lru_cache
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any,
|
|
10
|
+
from typing import Any, cast, Iterable
|
|
11
11
|
|
|
12
12
|
import regex as re
|
|
13
13
|
from lxml.etree import _Comment, _ElementTree, _Entity, _ProcessingInstruction, _Element
|
|
@@ -15,10 +15,11 @@ from lxml.etree import _Comment, _ElementTree, _Entity, _ProcessingInstruction,
|
|
|
15
15
|
from arelle import XbrlConst
|
|
16
16
|
from arelle.FunctionIxt import ixtNamespaces
|
|
17
17
|
from arelle.ModelDocument import ModelDocument, Type as ModelDocumentType
|
|
18
|
-
from arelle.ModelDtsObject import ModelConcept
|
|
18
|
+
from arelle.ModelDtsObject import ModelConcept, ModelRelationship
|
|
19
19
|
from arelle.ModelInstanceObject import ModelContext, ModelFact, ModelInlineFootnote, ModelUnit, ModelInlineFact
|
|
20
|
+
from arelle.ModelRelationshipSet import ModelRelationshipSet
|
|
20
21
|
from arelle.ModelObject import ModelObject
|
|
21
|
-
from arelle.ModelValue import QName
|
|
22
|
+
from arelle.ModelValue import QName, qname
|
|
22
23
|
from arelle.ModelXbrl import ModelXbrl
|
|
23
24
|
from arelle.typing import assert_type
|
|
24
25
|
from arelle.utils.PluginData import PluginData
|
|
@@ -28,6 +29,7 @@ from arelle.XmlValidate import lexicalPatterns
|
|
|
28
29
|
from arelle.XmlValidateConst import VALID
|
|
29
30
|
from .LinkbaseType import LinkbaseType
|
|
30
31
|
|
|
32
|
+
DEFAULT_MEMBER_ROLE_URI = 'https://www.nltaxonomie.nl/kvk/role/axis-defaults'
|
|
31
33
|
XBRLI_IDENTIFIER_PATTERN = re.compile(r"^(?!00)\d{8}$")
|
|
32
34
|
XBRLI_IDENTIFIER_SCHEMA = 'http://www.kvk.nl/kvk-id'
|
|
33
35
|
MAX_REPORT_PACKAGE_SIZE_MBS = 100
|
|
@@ -63,6 +65,14 @@ EFFECTIVE_KVK_GAAP_IFRS_ENTRYPOINT_FILES = frozenset((
|
|
|
63
65
|
'https://www.nltaxonomie.nl/kvk/2024-12-31/kvk-annual-report-ifrs-ext.xsd',
|
|
64
66
|
))
|
|
65
67
|
|
|
68
|
+
EFFECTIVE_KVK_GAAP_OTHER_ENTRYPOINT_FILES = frozenset((
|
|
69
|
+
'https://www.nltaxonomie.nl/kvk/2024-12-31/kvk-annual-report-other-gaap.xsd',
|
|
70
|
+
))
|
|
71
|
+
|
|
72
|
+
NON_DIMENSIONALIZED_LINE_ITEM_LINKROLES = frozenset((
|
|
73
|
+
'https://www.nltaxonomie.nl/kvk/role/lineitems-nondimensional-usage',
|
|
74
|
+
))
|
|
75
|
+
|
|
66
76
|
TAXONOMY_URLS_BY_YEAR = {
|
|
67
77
|
'2024': {
|
|
68
78
|
'https://www.nltaxonomie.nl/kvk/2024-12-31/kvk-annual-report-nlgaap-ext.xsd',
|
|
@@ -94,6 +104,25 @@ STANDARD_TAXONOMY_URLS = frozenset((
|
|
|
94
104
|
'https://www.w3.org/1999/xlink'
|
|
95
105
|
))
|
|
96
106
|
|
|
107
|
+
QN_DOMAIN_ITEM_TYPES = frozenset((
|
|
108
|
+
qname("{http://www.xbrl.org/dtr/type/2022-03-31}nonnum:domainItemType"),
|
|
109
|
+
))
|
|
110
|
+
|
|
111
|
+
SUPPORTED_IMAGE_TYPES_BY_IS_FILE = {
|
|
112
|
+
True: ('gif', 'jpg', 'jpeg', 'png'),
|
|
113
|
+
False: ('gif', 'jpeg', 'png'),
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@dataclass(frozen=True)
|
|
118
|
+
class AnchorData:
|
|
119
|
+
anchorsInDimensionalElrs: dict[str, frozenset[ModelRelationship]]
|
|
120
|
+
anchorsNotInBase: frozenset[ModelRelationship]
|
|
121
|
+
anchorsWithDimensionItem: frozenset[ModelRelationship]
|
|
122
|
+
anchorsWithDomainItem: frozenset[ModelRelationship]
|
|
123
|
+
extLineItemsNotAnchored: frozenset[ModelConcept]
|
|
124
|
+
extLineItemsWronglyAnchored: frozenset[ModelConcept]
|
|
125
|
+
|
|
97
126
|
|
|
98
127
|
@dataclass(frozen=True)
|
|
99
128
|
class ContextData:
|
|
@@ -103,6 +132,13 @@ class ContextData:
|
|
|
103
132
|
contextsWithSegments: list[ModelContext | None]
|
|
104
133
|
|
|
105
134
|
|
|
135
|
+
@dataclass(frozen=True)
|
|
136
|
+
class DimensionalData:
|
|
137
|
+
domainMembers: frozenset[ModelConcept]
|
|
138
|
+
elrPrimaryItems: dict[str, set[ModelConcept]]
|
|
139
|
+
primaryItems: frozenset[ModelConcept]
|
|
140
|
+
|
|
141
|
+
|
|
106
142
|
@dataclass(frozen=True)
|
|
107
143
|
class ExtensionData:
|
|
108
144
|
extensionConcepts: list[ModelConcept]
|
|
@@ -195,6 +231,12 @@ class PluginValidationDataExtension(PluginData):
|
|
|
195
231
|
def __hash__(self) -> int:
|
|
196
232
|
return id(self)
|
|
197
233
|
|
|
234
|
+
def addDomMbrs(self, modelXbrl: ModelXbrl, sourceDomMbr: ModelConcept, ELR: str, membersSet: set[ModelConcept]) -> None:
|
|
235
|
+
if isinstance(sourceDomMbr, ModelConcept) and sourceDomMbr not in membersSet:
|
|
236
|
+
membersSet.add(sourceDomMbr)
|
|
237
|
+
for domMbrRel in modelXbrl.relationshipSet(XbrlConst.domainMember, ELR).fromModelObject(sourceDomMbr):
|
|
238
|
+
self.addDomMbrs(modelXbrl, domMbrRel.toModelObject, domMbrRel.consecutiveLinkrole, membersSet)
|
|
239
|
+
|
|
198
240
|
@lru_cache(1)
|
|
199
241
|
def contextsByDocument(self, modelXbrl: ModelXbrl) -> dict[str, list[ModelContext]]:
|
|
200
242
|
contextsByDocument = defaultdict(list)
|
|
@@ -234,6 +276,23 @@ class PluginValidationDataExtension(PluginData):
|
|
|
234
276
|
contextsWithSegments=contextsWithSegments,
|
|
235
277
|
)
|
|
236
278
|
|
|
279
|
+
def checkLabels(self, issues: set[ModelConcept| None], modelXbrl: ModelXbrl, parent: ModelConcept, relSet: ModelRelationshipSet, labelrole: str | None, visited: set[ModelConcept]) -> set[ModelConcept| None]:
|
|
280
|
+
visited.add(parent)
|
|
281
|
+
conceptRels = defaultdict(list) # counts for concepts without preferred label role
|
|
282
|
+
for rel in relSet.fromModelObject(parent):
|
|
283
|
+
child = rel.toModelObject
|
|
284
|
+
if child is not None:
|
|
285
|
+
labelrole = rel.preferredLabel
|
|
286
|
+
if not labelrole:
|
|
287
|
+
conceptRels[child].append(rel)
|
|
288
|
+
if child not in visited:
|
|
289
|
+
self.checkLabels(issues, modelXbrl, child, relSet, labelrole, visited)
|
|
290
|
+
for concept, rels in conceptRels.items():
|
|
291
|
+
if len(rels) > 1:
|
|
292
|
+
issues.add(concept)
|
|
293
|
+
visited.remove(parent)
|
|
294
|
+
return issues
|
|
295
|
+
|
|
237
296
|
@lru_cache(1)
|
|
238
297
|
def checkHiddenElements(self, modelXbrl: ModelXbrl) -> HiddenElementsData:
|
|
239
298
|
cssHiddenFacts = set()
|
|
@@ -351,6 +410,70 @@ class PluginValidationDataExtension(PluginData):
|
|
|
351
410
|
factLangs.add(fact.xmlLang)
|
|
352
411
|
return factLangs
|
|
353
412
|
|
|
413
|
+
@lru_cache(1)
|
|
414
|
+
def getAnchorData(self, modelXbrl: ModelXbrl) -> AnchorData:
|
|
415
|
+
extLineItemsNotAnchored = set()
|
|
416
|
+
extLineItemsWronglyAnchored = set()
|
|
417
|
+
widerNarrowerRelSet = modelXbrl.relationshipSet(XbrlConst.widerNarrower)
|
|
418
|
+
generalSpecialRelSet = modelXbrl.relationshipSet(XbrlConst.generalSpecial)
|
|
419
|
+
calcRelSet = modelXbrl.relationshipSet(XbrlConst.summationItems)
|
|
420
|
+
dimensionalData = self.getDimensionalData(modelXbrl)
|
|
421
|
+
primaryItems = dimensionalData.primaryItems
|
|
422
|
+
domainMembers = dimensionalData.domainMembers
|
|
423
|
+
extensionData = self.getExtensionData(modelXbrl)
|
|
424
|
+
for concept in extensionData.extensionConcepts:
|
|
425
|
+
extLineItem = False
|
|
426
|
+
if concept.isPrimaryItem and \
|
|
427
|
+
not concept.isAbstract and \
|
|
428
|
+
concept in primaryItems and \
|
|
429
|
+
not widerNarrowerRelSet.contains(concept) and \
|
|
430
|
+
not calcRelSet.fromModelObject(concept):
|
|
431
|
+
extLineItem = True
|
|
432
|
+
elif concept.isAbstract and \
|
|
433
|
+
concept not in domainMembers and \
|
|
434
|
+
concept.type is not None and \
|
|
435
|
+
not concept.type.isDomainItemType and \
|
|
436
|
+
not concept.isHypercubeItem and \
|
|
437
|
+
not concept.isDimensionItem and \
|
|
438
|
+
not widerNarrowerRelSet.contains(concept):
|
|
439
|
+
extLineItem = True
|
|
440
|
+
if extLineItem:
|
|
441
|
+
if not generalSpecialRelSet.contains(concept):
|
|
442
|
+
extLineItemsNotAnchored.add(concept)
|
|
443
|
+
else:
|
|
444
|
+
extLineItemsWronglyAnchored.add(concept)
|
|
445
|
+
elrsContainingDimensionalRelationships = set(
|
|
446
|
+
ELR
|
|
447
|
+
for arcrole, ELR, linkqname, arcqname in modelXbrl.baseSets.keys()
|
|
448
|
+
if arcrole == "XBRL-dimensions" and ELR is not None)
|
|
449
|
+
anchorsNotInBase = set()
|
|
450
|
+
anchorsWithDomainItem = set()
|
|
451
|
+
anchorsWithDimensionItem = set()
|
|
452
|
+
anchorsInDimensionalElrs = defaultdict(set)
|
|
453
|
+
for anchoringRel in widerNarrowerRelSet.modelRelationships:
|
|
454
|
+
elr = anchoringRel.linkrole
|
|
455
|
+
fromObj = anchoringRel.fromModelObject
|
|
456
|
+
toObj = anchoringRel.toModelObject
|
|
457
|
+
if fromObj is not None and toObj is not None and fromObj.type is not None and toObj.type is not None:
|
|
458
|
+
if not ((not self.isExtensionUri(fromObj.modelDocument.uri, modelXbrl)) ^ (not self.isExtensionUri(toObj.modelDocument.uri, modelXbrl))):
|
|
459
|
+
anchorsNotInBase.add(anchoringRel)
|
|
460
|
+
if fromObj.type.isDomainItemType or toObj.type.isDomainItemType:
|
|
461
|
+
anchorsWithDomainItem.add(anchoringRel)
|
|
462
|
+
elif fromObj.isDimensionItem or toObj.isDimensionItem:
|
|
463
|
+
anchorsWithDimensionItem.add(anchoringRel)
|
|
464
|
+
else:
|
|
465
|
+
if elr in elrsContainingDimensionalRelationships:
|
|
466
|
+
anchorsInDimensionalElrs[elr].add(anchoringRel)
|
|
467
|
+
return AnchorData(
|
|
468
|
+
anchorsInDimensionalElrs={x: frozenset(y) for x, y in anchorsInDimensionalElrs.items()},
|
|
469
|
+
anchorsNotInBase=frozenset(anchorsNotInBase),
|
|
470
|
+
anchorsWithDimensionItem=frozenset(anchorsWithDimensionItem),
|
|
471
|
+
anchorsWithDomainItem=frozenset(anchorsWithDomainItem),
|
|
472
|
+
extLineItemsNotAnchored=frozenset(extLineItemsNotAnchored),
|
|
473
|
+
extLineItemsWronglyAnchored=frozenset(extLineItemsWronglyAnchored),
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
|
|
354
477
|
def getBaseElements(self, modelXbrl: ModelXbrl) -> set[Any | None]:
|
|
355
478
|
return self.checkInlineHTMLElements(modelXbrl).baseElements
|
|
356
479
|
|
|
@@ -384,6 +507,46 @@ class PluginValidationDataExtension(PluginData):
|
|
|
384
507
|
_getDocumentsInDts(modelXbrl.modelDocument)
|
|
385
508
|
return modelDocuments
|
|
386
509
|
|
|
510
|
+
@lru_cache(1)
|
|
511
|
+
def getDimensionalData(self, modelXbrl: ModelXbrl) -> DimensionalData:
|
|
512
|
+
domainMembers = set() # concepts which are dimension domain members
|
|
513
|
+
elrPrimaryItems = defaultdict(set)
|
|
514
|
+
hcPrimaryItems: set[ModelConcept] = set()
|
|
515
|
+
hcMembers: set[Any] = set()
|
|
516
|
+
primaryItems: set[ModelConcept] = set()
|
|
517
|
+
for hasHypercubeArcrole in (XbrlConst.all, XbrlConst.notAll):
|
|
518
|
+
hasHypercubeRelationships = modelXbrl.relationshipSet(hasHypercubeArcrole).fromModelObjects()
|
|
519
|
+
for hasHcRels in hasHypercubeRelationships.values():
|
|
520
|
+
for hasHcRel in hasHcRels:
|
|
521
|
+
sourceConcept: ModelConcept = hasHcRel.fromModelObject
|
|
522
|
+
hcPrimaryItems.add(sourceConcept)
|
|
523
|
+
# find associated primary items to source concept
|
|
524
|
+
for domMbrRel in modelXbrl.relationshipSet(XbrlConst.domainMember).fromModelObject(sourceConcept):
|
|
525
|
+
if domMbrRel.consecutiveLinkrole == hasHcRel.linkrole: # only those related to this hc
|
|
526
|
+
self.addDomMbrs(modelXbrl, domMbrRel.toModelObject, domMbrRel.consecutiveLinkrole, hcPrimaryItems)
|
|
527
|
+
primaryItems.update(hcPrimaryItems)
|
|
528
|
+
hc = hasHcRel.toModelObject
|
|
529
|
+
for hcDimRel in modelXbrl.relationshipSet(XbrlConst.hypercubeDimension, hasHcRel.consecutiveLinkrole).fromModelObject(hc):
|
|
530
|
+
dim = hcDimRel.toModelObject
|
|
531
|
+
if isinstance(dim, ModelConcept):
|
|
532
|
+
for dimDomRel in modelXbrl.relationshipSet(XbrlConst.dimensionDomain, hcDimRel.consecutiveLinkrole).fromModelObject(dim):
|
|
533
|
+
dom = dimDomRel.toModelObject
|
|
534
|
+
if isinstance(dom, ModelConcept):
|
|
535
|
+
self.addDomMbrs(modelXbrl, dom, dimDomRel.consecutiveLinkrole, hcMembers)
|
|
536
|
+
domainMembers.update(hcMembers)
|
|
537
|
+
if hasHcRel.linkrole in NON_DIMENSIONALIZED_LINE_ITEM_LINKROLES or hcMembers:
|
|
538
|
+
for hcPrimaryItem in hcPrimaryItems:
|
|
539
|
+
if not hcPrimaryItem.isAbstract:
|
|
540
|
+
elrPrimaryItems[hasHcRel.linkrole].add(hcPrimaryItem)
|
|
541
|
+
elrPrimaryItems["*"].add(hcPrimaryItem) # members of any ELR
|
|
542
|
+
hcPrimaryItems.clear()
|
|
543
|
+
hcMembers.clear()
|
|
544
|
+
return DimensionalData(
|
|
545
|
+
domainMembers=frozenset(domainMembers),
|
|
546
|
+
elrPrimaryItems=elrPrimaryItems,
|
|
547
|
+
primaryItems=frozenset(primaryItems),
|
|
548
|
+
)
|
|
549
|
+
|
|
387
550
|
def getEligibleForTransformHiddenFacts(self, modelXbrl: ModelXbrl) -> set[ModelInlineFact]:
|
|
388
551
|
return self.checkHiddenElements(modelXbrl).eligibleForTransformHiddenFacts
|
|
389
552
|
|
|
@@ -435,6 +598,7 @@ class PluginValidationDataExtension(PluginData):
|
|
|
435
598
|
def getIxdsDocBasenames(self, modelXbrl: ModelXbrl) -> set[str]:
|
|
436
599
|
return set(Path(url).name for url in getattr(modelXbrl, "ixdsDocUrls", []))
|
|
437
600
|
|
|
601
|
+
@lru_cache(1)
|
|
438
602
|
def getExtensionConcepts(self, modelXbrl: ModelXbrl) -> list[ModelConcept]:
|
|
439
603
|
"""
|
|
440
604
|
Returns a list of extension concepts in the DTS.
|
|
@@ -10,7 +10,9 @@ from arelle.ModelXbrl import ModelXbrl
|
|
|
10
10
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
11
11
|
from arelle.typing import TypeGetText
|
|
12
12
|
from arelle.utils.validate.ValidationPlugin import ValidationPlugin
|
|
13
|
-
from .DisclosureSystems import DISCLOSURE_SYSTEM_NT16, DISCLOSURE_SYSTEM_NT17, DISCLOSURE_SYSTEM_NT18,
|
|
13
|
+
from .DisclosureSystems import (DISCLOSURE_SYSTEM_NT16, DISCLOSURE_SYSTEM_NT17, DISCLOSURE_SYSTEM_NT18,
|
|
14
|
+
DISCLOSURE_SYSTEM_NT19, DISCLOSURE_SYSTEM_NL_INLINE_2024,
|
|
15
|
+
DISCLOSURE_SYSTEM_NL_INLINE_2024_GAAP_OTHER)
|
|
14
16
|
from .PluginValidationDataExtension import PluginValidationDataExtension
|
|
15
17
|
|
|
16
18
|
_: TypeGetText
|
|
@@ -174,6 +176,13 @@ class ValidationPluginExtension(ValidationPlugin):
|
|
|
174
176
|
entrypoints = {entrypointRoot + e for e in [
|
|
175
177
|
'kvk-annual-report-ifrs-ext.xsd',
|
|
176
178
|
'kvk-annual-report-nlgaap-ext.xsd',
|
|
179
|
+
]}
|
|
180
|
+
elif disclosureSystem == DISCLOSURE_SYSTEM_NL_INLINE_2024_GAAP_OTHER:
|
|
181
|
+
jenvNamespace = 'https://www.nltaxonomie.nl/bw2-titel9/2024-12-31/bw2-titel9-cor'
|
|
182
|
+
kvkINamespace = None
|
|
183
|
+
nlTypesNamespace = None
|
|
184
|
+
entrypointRoot = 'http://www.nltaxonomie.nl/kvk/2024-12-31/'
|
|
185
|
+
entrypoints = {entrypointRoot + e for e in [
|
|
177
186
|
'kvk-annual-report-other-gaap.xsd',
|
|
178
187
|
]}
|
|
179
188
|
else:
|
|
@@ -5,27 +5,38 @@
|
|
|
5
5
|
<!-- see arelle/config/disclosuresystems.xml for full comments -->
|
|
6
6
|
<DisclosureSystem
|
|
7
7
|
names="NL-INLINE-2024|nl-inline-2024|kvk-inline-2024-preview"
|
|
8
|
-
description="Checks for NL INLINE 2024"
|
|
8
|
+
description="Checks for NL INLINE 2024. For use with NL GAAP and NL IFRS"
|
|
9
9
|
validationType="NL"
|
|
10
|
+
exclusiveTypesPattern="EFM|GFM|FERC|HMRC|SBR.NL|EBA|EIOPA|ESEF"
|
|
11
|
+
/>
|
|
12
|
+
<DisclosureSystem
|
|
13
|
+
names="NL-INLINE-2024-GAAP-OTHER|nl-inline-2024-gaap-other|kvk-inline-2024-gaap-other-preview"
|
|
14
|
+
description="Checks for NL INLINE 2024. For use with other GAAP."
|
|
15
|
+
validationType="NL"
|
|
16
|
+
exclusiveTypesPattern="EFM|GFM|FERC|HMRC|SBR.NL|EBA|EIOPA|ESEF"
|
|
10
17
|
/>
|
|
11
18
|
<DisclosureSystem
|
|
12
19
|
names="NT19|nt19|NT19-preview|nt19-preview"
|
|
13
20
|
description="Checks for NT19"
|
|
14
21
|
validationType="NL"
|
|
22
|
+
exclusiveTypesPattern="EFM|GFM|FERC|HMRC|SBR.NL|EBA|EIOPA|ESEF"
|
|
15
23
|
/>
|
|
16
24
|
<DisclosureSystem
|
|
17
25
|
names="NT18|nt18|NT18-preview|nt18-preview"
|
|
18
26
|
description="Checks for NT18"
|
|
19
27
|
validationType="NL"
|
|
28
|
+
exclusiveTypesPattern="EFM|GFM|FERC|HMRC|SBR.NL|EBA|EIOPA|ESEF"
|
|
20
29
|
/>
|
|
21
30
|
<DisclosureSystem
|
|
22
31
|
names="NT17|nt17|NT17-preview|nt17-preview"
|
|
23
32
|
description="Checks for NT17"
|
|
24
33
|
validationType="NL"
|
|
34
|
+
exclusiveTypesPattern="EFM|GFM|FERC|HMRC|SBR.NL|EBA|EIOPA|ESEF"
|
|
25
35
|
/>
|
|
26
36
|
<DisclosureSystem
|
|
27
37
|
names="NT16|nt16|NT16-preview|nt16-preview"
|
|
28
38
|
description="Checks for NT16"
|
|
29
39
|
validationType="NL"
|
|
40
|
+
exclusiveTypesPattern="EFM|GFM|FERC|HMRC|SBR.NL|EBA|EIOPA|ESEF"
|
|
30
41
|
/>
|
|
31
42
|
</DisclosureSystems>
|
|
@@ -120,7 +120,7 @@ def rule_fr_kvk_2_02(
|
|
|
120
120
|
if fact.xmlLang and fact.xmlLang != lang:
|
|
121
121
|
yield Validation.error(
|
|
122
122
|
codes='NL.FR-KVK-2.02',
|
|
123
|
-
msg=_('The attribute \'xml:lang\' can be reported on different elements within an XBRL instance document.'
|
|
123
|
+
msg=_('The attribute \'xml:lang\' can be reported on different elements within an XBRL instance document. '
|
|
124
124
|
'The attribute \'xml:lang\' must always contain the same value within an XBRL instance document. '
|
|
125
125
|
'It is not allowed to report different values here. Document language: %(documentLang)s Element language: %(additionalLang)s'),
|
|
126
126
|
modelObject=fact,
|