arelle-release 2.37.36__py3-none-any.whl → 2.37.38__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/ModelTestcaseObject.py +5 -1
- arelle/ModelXbrl.py +10 -0
- arelle/XbrlConst.py +5 -0
- arelle/_version.py +2 -2
- arelle/plugin/validate/EDINET/rules/edinet.py +46 -0
- arelle/plugin/validate/EDINET/rules/frta.py +137 -3
- arelle/plugin/validate/EDINET/rules/gfm.py +180 -1
- arelle/plugin/validate/ESEF/resources/authority-validations.json +10 -1
- arelle/plugin/validate/NL/PluginValidationDataExtension.py +2 -12
- arelle/plugin/validate/NL/ValidationPluginExtension.py +28 -27
- arelle/plugin/validate/NL/rules/fg_nl.py +1 -1
- arelle/plugin/validate/NL/rules/fr_nl.py +2 -1
- arelle/plugin/validate/NL/rules/nl_kvk.py +7 -9
- {arelle_release-2.37.36.dist-info → arelle_release-2.37.38.dist-info}/METADATA +1 -1
- {arelle_release-2.37.36.dist-info → arelle_release-2.37.38.dist-info}/RECORD +19 -19
- {arelle_release-2.37.36.dist-info → arelle_release-2.37.38.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.36.dist-info → arelle_release-2.37.38.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.36.dist-info → arelle_release-2.37.38.dist-info}/licenses/LICENSE.md +0 -0
- {arelle_release-2.37.36.dist-info → arelle_release-2.37.38.dist-info}/top_level.txt +0 -0
arelle/ModelTestcaseObject.py
CHANGED
|
@@ -363,7 +363,11 @@ class ModelTestcaseVariation(ModelObject):
|
|
|
363
363
|
def expectedWarnings(self):
|
|
364
364
|
warningElements = XmlUtil.descendants(self, None, "warning")
|
|
365
365
|
if isinstance(warningElements, list) and len(warningElements) > 0:
|
|
366
|
-
|
|
366
|
+
warningCodes = []
|
|
367
|
+
for warningElement in warningElements:
|
|
368
|
+
num = int(warningElement.attr("num") or 1)
|
|
369
|
+
warningCodes.extend([warningElement.stringValue] * num)
|
|
370
|
+
return warningCodes
|
|
367
371
|
return None
|
|
368
372
|
|
|
369
373
|
@property
|
arelle/ModelXbrl.py
CHANGED
|
@@ -422,6 +422,16 @@ class ModelXbrl:
|
|
|
422
422
|
else:
|
|
423
423
|
return self.fileSource.url
|
|
424
424
|
|
|
425
|
+
def contextsByDocument(self) -> dict[str, list[ModelContext]]:
|
|
426
|
+
contextsByDocument = defaultdict(list)
|
|
427
|
+
for context in self.contexts.values():
|
|
428
|
+
contextsByDocument[context.modelDocument.filepath].append(context)
|
|
429
|
+
contextsByDocument.default_factory = None
|
|
430
|
+
return contextsByDocument
|
|
431
|
+
|
|
432
|
+
def entityIdentifiersInDocument(self) -> set[tuple[str, str]]:
|
|
433
|
+
return {context.entityIdentifier for context in self.contexts.values()}
|
|
434
|
+
|
|
425
435
|
def relationshipSet(self, arcrole: tuple[str, ...] | str, linkrole: tuple[str, ...] | str | None = None, linkqname: QName | None = None, arcqname: QName | None = None, includeProhibits: bool = False) -> ModelRelationshipSetClass:
|
|
426
436
|
"""Returns a relationship set matching specified parameters (only arcrole is required).
|
|
427
437
|
|
arelle/XbrlConst.py
CHANGED
|
@@ -38,6 +38,8 @@ builtinAttributes = {
|
|
|
38
38
|
qnXsiSchemaLocation,
|
|
39
39
|
qnXsiNoNamespaceSchemaLocation,
|
|
40
40
|
}
|
|
41
|
+
ref2004 = "http://www.xbrl.org/2004/ref"
|
|
42
|
+
ref2006 = "http://www.xbrl.org/2006/ref"
|
|
41
43
|
xml = "http://www.w3.org/XML/1998/namespace"
|
|
42
44
|
xbrli = "http://www.xbrl.org/2003/instance"
|
|
43
45
|
xhtmlBaseIdentifier = "{http://www.w3.org/1999/xhtml}base"
|
|
@@ -45,6 +47,7 @@ xmlBaseIdentifier = "{http://www.w3.org/XML/1998/namespace}base"
|
|
|
45
47
|
eurofilingModelNamespace = "http://www.eurofiling.info/xbrl/ext/model"
|
|
46
48
|
eurofilingModelPrefix = "model"
|
|
47
49
|
qnNsmap = qname("nsmap") # artificial parent for insertion of xmlns in saving xml documents
|
|
50
|
+
qnXbrlScenario = qname("{http://www.xbrl.org/2003/instance}scenario")
|
|
48
51
|
qnXbrliXbrl = qname("{http://www.xbrl.org/2003/instance}xbrli:xbrl")
|
|
49
52
|
qnPrototypeXbrliXbrl = qname(
|
|
50
53
|
"{http://arelle.org/prototype/xbrli}xbrl"
|
|
@@ -58,6 +61,7 @@ qnXbrliPeriod = qname("{http://www.xbrl.org/2003/instance}xbrli:period")
|
|
|
58
61
|
qnXbrliStartDate = qname("{http://www.xbrl.org/2003/instance}xbrli:startDate")
|
|
59
62
|
qnXbrliEndDate = qname("{http://www.xbrl.org/2003/instance}xbrli:endDate")
|
|
60
63
|
qnXbrliInstant = qname("{http://www.xbrl.org/2003/instance}xbrli:instant")
|
|
64
|
+
qnXbrliForever = qname("{http://www.xbrl.org/2003/instance}xbrli:forever")
|
|
61
65
|
qnXbrliIdentifier = qname("{http://www.xbrl.org/2003/instance}xbrli:identifier")
|
|
62
66
|
qnXbrliUnit = qname("{http://www.xbrl.org/2003/instance}xbrli:unit")
|
|
63
67
|
qnXbrliStringItemType = qname("{http://www.xbrl.org/2003/instance}xbrli:stringItemType")
|
|
@@ -138,6 +142,7 @@ ixbrl11 = "http://www.xbrl.org/2013/inlineXBRL"
|
|
|
138
142
|
ixbrlAll = {ixbrl, ixbrl11}
|
|
139
143
|
ixbrlTags = ("{http://www.xbrl.org/2013/inlineXBRL}*", "{http://www.xbrl.org/2008/inlineXBRL}*")
|
|
140
144
|
ixbrlTagPattern = re.compile("[{]http://www.xbrl.org/(2008|2013)/inlineXBRL[}]")
|
|
145
|
+
ixt = "http://www.xbrl.org/inlineXBRL/transformation/2010-04-20"
|
|
141
146
|
qnIXbrlResources = qname("{http://www.xbrl.org/2008/inlineXBRL}resources")
|
|
142
147
|
qnIXbrlTuple = qname("{http://www.xbrl.org/2008/inlineXBRL}tuple")
|
|
143
148
|
qnIXbrlNonNumeric = qname("{http://www.xbrl.org/2008/inlineXBRL}nonNumeric")
|
arelle/_version.py
CHANGED
|
@@ -3,6 +3,7 @@ See COPYRIGHT.md for copyright information.
|
|
|
3
3
|
"""
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
+
import itertools
|
|
6
7
|
from collections.abc import Iterable
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
@@ -59,3 +60,48 @@ def rule_EC5002E(
|
|
|
59
60
|
qname=fact.qname.clarkNotation,
|
|
60
61
|
modelObject=fact,
|
|
61
62
|
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@validation(
|
|
66
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
67
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
68
|
+
)
|
|
69
|
+
def rule_EC8033W(
|
|
70
|
+
pluginData: PluginValidationDataExtension,
|
|
71
|
+
val: ValidateXbrl,
|
|
72
|
+
*args: Any,
|
|
73
|
+
**kwargs: Any,
|
|
74
|
+
) -> Iterable[Validation]:
|
|
75
|
+
"""
|
|
76
|
+
EDINET.EC8033W: The startDate of a context whose context ID starts with
|
|
77
|
+
"CurrentYear" is not set to a date earlier than the endDate of a context
|
|
78
|
+
whose context ID starts with "Prior1Year".
|
|
79
|
+
"""
|
|
80
|
+
priorYearContexts = [
|
|
81
|
+
context
|
|
82
|
+
for contextId, context in val.modelXbrl.contexts.items()
|
|
83
|
+
if contextId.startswith('Prior1Year')
|
|
84
|
+
and context.endDatetime is not None
|
|
85
|
+
and context.isStartEndPeriod
|
|
86
|
+
]
|
|
87
|
+
currentYearContexts = [
|
|
88
|
+
context
|
|
89
|
+
for contextId, context in val.modelXbrl.contexts.items()
|
|
90
|
+
if contextId.startswith('CurrentYear')
|
|
91
|
+
and context.startDatetime is not None
|
|
92
|
+
and context.isStartEndPeriod
|
|
93
|
+
]
|
|
94
|
+
for priorYearContext, currentYearContext in itertools.product(priorYearContexts, currentYearContexts):
|
|
95
|
+
if priorYearContext.endDatetime > currentYearContext.startDatetime:
|
|
96
|
+
yield Validation.warning(
|
|
97
|
+
codes='EDINET.EC8033W',
|
|
98
|
+
msg=_("The startDate element of the current year context (id=%(currentYearContextId)s) is "
|
|
99
|
+
"set to a date that is earlier than the endDate element of the prior year context "
|
|
100
|
+
"(id=%(priorYearContextId)s). Please check the corresponding context ID "
|
|
101
|
+
"%(currentYearContextId)s and %(priorYearContextId)s. Set the startDate element of "
|
|
102
|
+
"context ID %(currentYearContextId)s to a date that is later than or equal to the "
|
|
103
|
+
"endDate element of context ID %(priorYearContextId)s."),
|
|
104
|
+
currentYearContextId=currentYearContext.id,
|
|
105
|
+
priorYearContextId=priorYearContext.id,
|
|
106
|
+
modelObject=(priorYearContext, currentYearContext),
|
|
107
|
+
)
|
|
@@ -3,10 +3,11 @@ See COPYRIGHT.md for copyright information.
|
|
|
3
3
|
"""
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
-
from collections
|
|
7
|
-
from typing import Any
|
|
6
|
+
from collections import defaultdict
|
|
7
|
+
from typing import Any, Iterable
|
|
8
8
|
|
|
9
9
|
from arelle import XbrlConst
|
|
10
|
+
from arelle.ModelDtsObject import ModelResource, ModelConcept
|
|
10
11
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
11
12
|
from arelle.typing import TypeGetText
|
|
12
13
|
from arelle.utils.PluginHooks import ValidationHook
|
|
@@ -40,9 +41,142 @@ def rule_frta_2_1_9(
|
|
|
40
41
|
for elt in rootElt.iterdescendants(XbrlConst.qnXsdDocumentation.clarkNotation):
|
|
41
42
|
errors.append(elt)
|
|
42
43
|
if len(errors) > 0:
|
|
43
|
-
yield Validation.
|
|
44
|
+
yield Validation.warning(
|
|
44
45
|
codes='EDINET.EC5710W.FRTA.2.1.9',
|
|
45
46
|
msg=_("All documentation of a concept must be contained in XBRL linkbases. "
|
|
46
47
|
"Taxonomy element declarations should not use the XML Schema documentation element."),
|
|
47
48
|
modelObject=errors,
|
|
48
49
|
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@validation(
|
|
53
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
54
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
55
|
+
)
|
|
56
|
+
def rule_frta_2_1_10(
|
|
57
|
+
pluginData: PluginValidationDataExtension,
|
|
58
|
+
val: ValidateXbrl,
|
|
59
|
+
*args: Any,
|
|
60
|
+
**kwargs: Any,
|
|
61
|
+
) -> Iterable[Validation]:
|
|
62
|
+
"""
|
|
63
|
+
EDINET: [FRTA.2.1.10] All extension taxonomy concepts must have a standard label.
|
|
64
|
+
"""
|
|
65
|
+
errors = []
|
|
66
|
+
for concept in val.modelXbrl.qnameConcepts.values():
|
|
67
|
+
if pluginData.isStandardTaxonomyUrl(concept.modelDocument.uri, val.modelXbrl):
|
|
68
|
+
continue
|
|
69
|
+
if not concept.label(XbrlConst.standardLabel, fallbackToQname=False):
|
|
70
|
+
errors.append(concept)
|
|
71
|
+
if len(errors) > 0:
|
|
72
|
+
yield Validation.warning(
|
|
73
|
+
codes='EDINET.FRTA.2.1.10', # Not associated with EC5710W code.
|
|
74
|
+
msg=_("All extension taxonomy concepts must have a standard label. "
|
|
75
|
+
"A standard label is not specified for a concept in an "
|
|
76
|
+
"extension taxonomy. When adding a concept to an extension taxonomy, "
|
|
77
|
+
"please provide Japanese and English labels in the standard, verbose, and "
|
|
78
|
+
"documentation roles."),
|
|
79
|
+
modelObject=errors,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@validation(
|
|
84
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
85
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
86
|
+
)
|
|
87
|
+
def rule_frta_2_1_11(
|
|
88
|
+
pluginData: PluginValidationDataExtension,
|
|
89
|
+
val: ValidateXbrl,
|
|
90
|
+
*args: Any,
|
|
91
|
+
**kwargs: Any,
|
|
92
|
+
) -> Iterable[Validation]:
|
|
93
|
+
"""
|
|
94
|
+
EDINET.EC5710W: [FRTA.2.1.11] All concepts within a taxonomy schema should have a
|
|
95
|
+
unique label for the standard or verbose role in each language used.
|
|
96
|
+
"""
|
|
97
|
+
labelsRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
|
|
98
|
+
labelGroupsByLang: dict[str, dict[str, dict[str, set[ModelConcept]]]] = (
|
|
99
|
+
defaultdict(lambda: defaultdict(lambda: defaultdict(set)))
|
|
100
|
+
)
|
|
101
|
+
relevantRoles = frozenset({
|
|
102
|
+
XbrlConst.standardLabel,
|
|
103
|
+
XbrlConst.verboseLabel
|
|
104
|
+
})
|
|
105
|
+
for concept, modelLabelRels in labelsRelationshipSet.fromModelObjects().items():
|
|
106
|
+
if pluginData.isStandardTaxonomyUrl(concept.modelDocument.uri, val.modelXbrl):
|
|
107
|
+
continue
|
|
108
|
+
for modelLabelRel in modelLabelRels:
|
|
109
|
+
modelLabel = modelLabelRel.toModelObject
|
|
110
|
+
if not isinstance(modelLabel, ModelResource):
|
|
111
|
+
continue
|
|
112
|
+
if modelLabel.role not in relevantRoles:
|
|
113
|
+
continue
|
|
114
|
+
if not modelLabel.modelDocument.inDTS:
|
|
115
|
+
continue
|
|
116
|
+
if not modelLabel.xmlLang:
|
|
117
|
+
continue
|
|
118
|
+
labelGroupsByLang[modelLabel.xmlLang][modelLabel.role][modelLabel.textValue].add(concept)
|
|
119
|
+
for lang, labelGroupsByRole in labelGroupsByLang.items():
|
|
120
|
+
duplicateLabelsByRole = defaultdict(list)
|
|
121
|
+
conceptsWithVerboseLabel = {
|
|
122
|
+
concept: False
|
|
123
|
+
for concept in val.modelXbrl.qnameConcepts.values()
|
|
124
|
+
if not pluginData.isStandardTaxonomyUrl(concept.modelDocument.uri, val.modelXbrl)
|
|
125
|
+
}
|
|
126
|
+
for role, labelGroupsByValue in labelGroupsByRole.items():
|
|
127
|
+
for value, concepts in labelGroupsByValue.items():
|
|
128
|
+
if role == XbrlConst.verboseLabel:
|
|
129
|
+
for concept in concepts:
|
|
130
|
+
conceptsWithVerboseLabel[concept] = True
|
|
131
|
+
if len(concepts) < 2:
|
|
132
|
+
continue
|
|
133
|
+
duplicateLabelsByRole[role].append((value, concepts))
|
|
134
|
+
if len(duplicateLabelsByRole[XbrlConst.standardLabel]) == 0:
|
|
135
|
+
# There are no duplicate standard labels, so we don't need to check verbose labels
|
|
136
|
+
continue
|
|
137
|
+
conceptsWithoutVerboseLabel = {concept for concept, value in conceptsWithVerboseLabel.items() if not value}
|
|
138
|
+
if len(duplicateLabelsByRole[XbrlConst.verboseLabel]) == 0 and len(conceptsWithoutVerboseLabel) == 0:
|
|
139
|
+
# All concepts have a verbose label, and there are no duplicate verbose labels,
|
|
140
|
+
return
|
|
141
|
+
for role, duplicateLabels in duplicateLabelsByRole.items():
|
|
142
|
+
for value, concepts in duplicateLabels:
|
|
143
|
+
yield Validation.warning(
|
|
144
|
+
codes='EDINET.EC5710W.FRTA.2.1.11',
|
|
145
|
+
msg=_("All concepts within a taxonomy schema should have a unique label for the "
|
|
146
|
+
"standard or verbose role in each language used. "
|
|
147
|
+
"The %(role)s label contains a duplicate label ('%(value)s') in the same "
|
|
148
|
+
"language ('%(lang)s'). Define either the standard label or the verbose label "
|
|
149
|
+
"so that they are unique in the same language."),
|
|
150
|
+
role='standard' if role == XbrlConst.standardLabel else 'verbose',
|
|
151
|
+
value=value,
|
|
152
|
+
lang=lang,
|
|
153
|
+
modelObject=concepts,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@validation(
|
|
158
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
159
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
160
|
+
)
|
|
161
|
+
def rule_frta_3_1_10(
|
|
162
|
+
pluginData: PluginValidationDataExtension,
|
|
163
|
+
val: ValidateXbrl,
|
|
164
|
+
*args: Any,
|
|
165
|
+
**kwargs: Any,
|
|
166
|
+
) -> Iterable[Validation]:
|
|
167
|
+
"""
|
|
168
|
+
EDINET.EC5710W: [FRTA.3.1.10] Role types defined in the extension taxonomy must have a definition.
|
|
169
|
+
"""
|
|
170
|
+
errors = []
|
|
171
|
+
for uri, roleTypes in val.modelXbrl.roleTypes.items():
|
|
172
|
+
for roleType in roleTypes:
|
|
173
|
+
if pluginData.isStandardTaxonomyUrl(roleType.document.uri, val.modelXbrl):
|
|
174
|
+
continue
|
|
175
|
+
if not roleType.definition:
|
|
176
|
+
errors.append(roleType)
|
|
177
|
+
if len(errors) > 0:
|
|
178
|
+
yield Validation.warning(
|
|
179
|
+
codes='EDINET.EC5710W.FRTA.3.1.10',
|
|
180
|
+
msg=_("Role types defined in the extension taxonomy must have a definition."),
|
|
181
|
+
modelObject=errors,
|
|
182
|
+
)
|
|
@@ -13,7 +13,7 @@ from arelle.PrototypeDtsObject import LocPrototype, ArcPrototype
|
|
|
13
13
|
from arelle.UrlUtil import isHttpUrl, splitDecodeFragment
|
|
14
14
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
15
15
|
from arelle.ValidateXbrlCalcs import insignificantDigits
|
|
16
|
-
from arelle.XbrlConst import xhtmlBaseIdentifier, xmlBaseIdentifier
|
|
16
|
+
from arelle.XbrlConst import qnXbrlScenario, qnXbrldiExplicitMember, xhtmlBaseIdentifier, xmlBaseIdentifier
|
|
17
17
|
from arelle.XmlValidate import VALID
|
|
18
18
|
from arelle.typing import TypeGetText
|
|
19
19
|
from arelle.utils.PluginHooks import ValidationHook
|
|
@@ -26,6 +26,21 @@ from ..PluginValidationDataExtension import PluginValidationDataExtension
|
|
|
26
26
|
_: TypeGetText
|
|
27
27
|
|
|
28
28
|
GFM_CONTEXT_DATE_PATTERN = regex.compile(r"^[12][0-9]{3}-[01][0-9]-[0-3][0-9]$")
|
|
29
|
+
GFM_RECOMMENDED_NAMESPACE_PREFIXES = {
|
|
30
|
+
XbrlConst.xbrli: ("xbrli",),
|
|
31
|
+
XbrlConst.xsi: ("xsi",),
|
|
32
|
+
XbrlConst.xsd: ("xs", "xsd",),
|
|
33
|
+
XbrlConst.link: ("link",),
|
|
34
|
+
XbrlConst.xl: ("xl",),
|
|
35
|
+
XbrlConst.xlink: ("xlink",),
|
|
36
|
+
XbrlConst.ref2004: ("ref",),
|
|
37
|
+
XbrlConst.ref2006: ("ref",),
|
|
38
|
+
XbrlConst.xbrldt: ("xbrldt",),
|
|
39
|
+
XbrlConst.xbrldi: ("xbrldi",),
|
|
40
|
+
XbrlConst.ixbrl: ("ix",),
|
|
41
|
+
XbrlConst.ixt: ("ixt",),
|
|
42
|
+
XbrlConst.xhtml: ("xhtml",),
|
|
43
|
+
}
|
|
29
44
|
|
|
30
45
|
|
|
31
46
|
@validation(
|
|
@@ -117,6 +132,88 @@ def rule_gfm_1_1_7(
|
|
|
117
132
|
)
|
|
118
133
|
|
|
119
134
|
|
|
135
|
+
@validation(
|
|
136
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
137
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
138
|
+
)
|
|
139
|
+
def rule_gfm_1_2_3(
|
|
140
|
+
pluginData: PluginValidationDataExtension,
|
|
141
|
+
val: ValidateXbrl,
|
|
142
|
+
*args: Any,
|
|
143
|
+
**kwargs: Any,
|
|
144
|
+
) -> Iterable[Validation]:
|
|
145
|
+
"""
|
|
146
|
+
EDINET.EC5700W: [GFM 1.2.3] All xbrli:identifier elements in an instance must have identical content.
|
|
147
|
+
"""
|
|
148
|
+
entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
|
|
149
|
+
if len(entityIdentifierValues) >1:
|
|
150
|
+
yield Validation.warning(
|
|
151
|
+
codes='EDINET.EC5700W.GFM.1.2.3',
|
|
152
|
+
msg=_('All identifier elements must be identical.'),
|
|
153
|
+
modelObject = val.modelXbrl
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@validation(
|
|
158
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
159
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
160
|
+
)
|
|
161
|
+
def rule_gfm_1_2_4(
|
|
162
|
+
pluginData: PluginValidationDataExtension,
|
|
163
|
+
val: ValidateXbrl,
|
|
164
|
+
*args: Any,
|
|
165
|
+
**kwargs: Any,
|
|
166
|
+
) -> Iterable[Validation]:
|
|
167
|
+
"""
|
|
168
|
+
EDINET.EC5700W: [GFM 1.2.4] Segment must not be used in the context.
|
|
169
|
+
"""
|
|
170
|
+
allContexts = val.modelXbrl.contextsByDocument()
|
|
171
|
+
contextsWithSegments =[]
|
|
172
|
+
for contexts in allContexts.values():
|
|
173
|
+
for context in contexts:
|
|
174
|
+
if context.hasSegment:
|
|
175
|
+
contextsWithSegments.append(context)
|
|
176
|
+
if len(contextsWithSegments) > 0:
|
|
177
|
+
yield Validation.warning(
|
|
178
|
+
codes='EDINET.EC5700W.GFM.1.2.4',
|
|
179
|
+
msg=_('Set the scenario element in the context. Do not set the segment element.'),
|
|
180
|
+
modelObject = contextsWithSegments
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@validation(
|
|
185
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
186
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
187
|
+
)
|
|
188
|
+
def rule_gfm_1_2_5(
|
|
189
|
+
pluginData: PluginValidationDataExtension,
|
|
190
|
+
val: ValidateXbrl,
|
|
191
|
+
*args: Any,
|
|
192
|
+
**kwargs: Any,
|
|
193
|
+
) -> Iterable[Validation]:
|
|
194
|
+
"""
|
|
195
|
+
EDINET.EC5700W: [GFM 1.2.5] If an xbrli:scenario element appears in a context, then its children
|
|
196
|
+
must be one or more xbrldi:explicitMember elements.
|
|
197
|
+
"""
|
|
198
|
+
allContexts = val.modelXbrl.contextsByDocument()
|
|
199
|
+
contextsWithDisallowedScenarioChildren =[]
|
|
200
|
+
for contexts in allContexts.values():
|
|
201
|
+
for context in contexts:
|
|
202
|
+
for elt in context.iterdescendants(qnXbrlScenario.clarkNotation):
|
|
203
|
+
if isinstance(elt, ModelObject):
|
|
204
|
+
if any(isinstance(child, ModelObject) and child.tag != qnXbrldiExplicitMember.clarkNotation
|
|
205
|
+
for child in elt.iterchildren()):
|
|
206
|
+
contextsWithDisallowedScenarioChildren.append(context)
|
|
207
|
+
if len(contextsWithDisallowedScenarioChildren) > 0:
|
|
208
|
+
yield Validation.warning(
|
|
209
|
+
codes='EDINET.EC5700W.GFM.1.2.5',
|
|
210
|
+
msg=_('Please delete all child elements other than the xbrldi:explicitMember '
|
|
211
|
+
'element from the segment element or scenario element.'),
|
|
212
|
+
modelObject = contextsWithDisallowedScenarioChildren
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
120
217
|
@validation(
|
|
121
218
|
hook=ValidationHook.XBRL_FINALLY,
|
|
122
219
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -268,3 +365,85 @@ def rule_gfm_1_2_26(
|
|
|
268
365
|
"decimals attribute."),
|
|
269
366
|
modelObject=errors,
|
|
270
367
|
)
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
@validation(
|
|
371
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
372
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
373
|
+
)
|
|
374
|
+
def rule_gfm_1_2_27(
|
|
375
|
+
pluginData: PluginValidationDataExtension,
|
|
376
|
+
val: ValidateXbrl,
|
|
377
|
+
*args: Any,
|
|
378
|
+
**kwargs: Any,
|
|
379
|
+
) -> Iterable[Validation]:
|
|
380
|
+
"""
|
|
381
|
+
EDINET.EC5700W: [GFM 1.2.27] An instance must not contain unused units.
|
|
382
|
+
"""
|
|
383
|
+
# TODO: Consolidate validations involving unused units
|
|
384
|
+
unusedUnits = set(val.modelXbrl.units.values()) - {fact.unit for fact in val.modelXbrl.facts if fact.unit is not None}
|
|
385
|
+
if len(unusedUnits) > 0:
|
|
386
|
+
yield Validation.warning(
|
|
387
|
+
codes='EDINET.EC5700W.GFM.1.2.27',
|
|
388
|
+
msg=_("Delete unused units from the instance."),
|
|
389
|
+
modelObject=list(unusedUnits)
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
@validation(
|
|
394
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
395
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
396
|
+
)
|
|
397
|
+
def rule_gfm_1_2_28(
|
|
398
|
+
pluginData: PluginValidationDataExtension,
|
|
399
|
+
val: ValidateXbrl,
|
|
400
|
+
*args: Any,
|
|
401
|
+
**kwargs: Any,
|
|
402
|
+
) -> Iterable[Validation]:
|
|
403
|
+
"""
|
|
404
|
+
EDINET.EC5700W: [GFM 1.2.28] The prefix declaration for the namespace is incorrect.
|
|
405
|
+
"""
|
|
406
|
+
for doc in val.modelXbrl.urlDocs.values():
|
|
407
|
+
rootElt = doc.xmlRootElement
|
|
408
|
+
for prefix, namespace in rootElt.nsmap.items():
|
|
409
|
+
if prefix is None:
|
|
410
|
+
continue
|
|
411
|
+
if namespace not in GFM_RECOMMENDED_NAMESPACE_PREFIXES:
|
|
412
|
+
continue
|
|
413
|
+
if prefix in GFM_RECOMMENDED_NAMESPACE_PREFIXES[namespace]:
|
|
414
|
+
continue
|
|
415
|
+
yield Validation.warning(
|
|
416
|
+
codes='EDINET.EC5700W.GFM.1.2.28',
|
|
417
|
+
msg=_("The prefix declaration '%(prefix)s' for the namespace '%(namespace)s' "
|
|
418
|
+
"is incorrect. "
|
|
419
|
+
"Correct the prefix (%(prefixes)s)."),
|
|
420
|
+
prefix=prefix,
|
|
421
|
+
namespace=namespace,
|
|
422
|
+
prefixes=", ".join(GFM_RECOMMENDED_NAMESPACE_PREFIXES[namespace]),
|
|
423
|
+
modelObject=rootElt
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
@validation(
|
|
428
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
429
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
430
|
+
)
|
|
431
|
+
def rule_gfm_1_2_30(
|
|
432
|
+
pluginData: PluginValidationDataExtension,
|
|
433
|
+
val: ValidateXbrl,
|
|
434
|
+
*args: Any,
|
|
435
|
+
**kwargs: Any,
|
|
436
|
+
) -> Iterable[Validation]:
|
|
437
|
+
"""
|
|
438
|
+
EDINET.EC5700W: [GFM 1.2.30] A context must not contain the xbrli:forever element.
|
|
439
|
+
"""
|
|
440
|
+
errors = []
|
|
441
|
+
for context in val.modelXbrl.contexts.values():
|
|
442
|
+
for elt in context.iterdescendants(XbrlConst.qnXbrliForever.clarkNotation):
|
|
443
|
+
errors.append(elt)
|
|
444
|
+
if len(errors) > 0:
|
|
445
|
+
yield Validation.warning(
|
|
446
|
+
codes='EDINET.EC5700W.GFM.1.2.30',
|
|
447
|
+
msg=_("A context must not contain the xbrli:forever element."),
|
|
448
|
+
modelObject=errors
|
|
449
|
+
)
|
|
@@ -344,10 +344,19 @@
|
|
|
344
344
|
"formulaRunIDs": "(?!con_IdentifierSchemeMustBeLEI|lei-identifier-scheme)"
|
|
345
345
|
},
|
|
346
346
|
"UKFRC-2023": {
|
|
347
|
+
"name": "United Kingdom Multiple Targets",
|
|
348
|
+
"authorityName": "FRC",
|
|
349
|
+
"comment": "This is a deprecated authority that will be removed. Use UKFRC instead.",
|
|
350
|
+
"reference": "https://media.frc.org.uk/documents/XBRL_Tagging_Guide_-_FRC_Taxonomies_2024_On9jOuS.pdf",
|
|
351
|
+
"reportPackageMaxMB": "150",
|
|
352
|
+
"reportPackageMeasurement": "zipped",
|
|
353
|
+
"ixTargetUsage": "allowed"
|
|
354
|
+
},
|
|
355
|
+
"UKFRC": {
|
|
347
356
|
"name": "United Kingdom Multiple Targets",
|
|
348
357
|
"authorityName": "FRC",
|
|
349
358
|
"comment": "Pertains to multi target UKSEF Guidance",
|
|
350
|
-
"comment2": "See UKFRC for reports prior to 2023 which did not use separate targets for FRC and ESEF",
|
|
359
|
+
"comment2": "See UKFRC-2022 for reports prior to 2023 which did not use separate targets for FRC and ESEF",
|
|
351
360
|
"reference": "https://media.frc.org.uk/documents/XBRL_Tagging_Guide_-_FRC_Taxonomies_2024_On9jOuS.pdf",
|
|
352
361
|
"reportPackageMaxMB": "150",
|
|
353
362
|
"reportPackageMeasurement": "zipped",
|
|
@@ -225,7 +225,7 @@ class PluginValidationDataExtension(PluginData):
|
|
|
225
225
|
financialReportingPeriodCurrentEndDateQn: QName
|
|
226
226
|
financialReportingPeriodPreviousStartDateQn: QName
|
|
227
227
|
financialReportingPeriodPreviousEndDateQn: QName
|
|
228
|
-
formattedExplanationItemTypeQn: QName
|
|
228
|
+
formattedExplanationItemTypeQn: QName | None
|
|
229
229
|
ifrsIdentifier: str
|
|
230
230
|
permissibleGAAPRootAbstracts: frozenset[QName]
|
|
231
231
|
permissibleIFRSRootAbstracts: frozenset[QName]
|
|
@@ -242,17 +242,10 @@ class PluginValidationDataExtension(PluginData):
|
|
|
242
242
|
for domMbrRel in modelXbrl.relationshipSet(XbrlConst.domainMember, ELR).fromModelObject(sourceDomMbr):
|
|
243
243
|
self.addDomMbrs(modelXbrl, domMbrRel.toModelObject, domMbrRel.consecutiveLinkrole, membersSet)
|
|
244
244
|
|
|
245
|
-
@lru_cache(1)
|
|
246
|
-
def contextsByDocument(self, modelXbrl: ModelXbrl) -> dict[str, list[ModelContext]]:
|
|
247
|
-
contextsByDocument = defaultdict(list)
|
|
248
|
-
for context in modelXbrl.contexts.values():
|
|
249
|
-
contextsByDocument[context.modelDocument.filepath].append(context)
|
|
250
|
-
contextsByDocument.default_factory = None
|
|
251
|
-
return contextsByDocument
|
|
252
245
|
|
|
253
246
|
@lru_cache(1)
|
|
254
247
|
def checkContexts(self, modelXbrl: ModelXbrl) -> ContextData:
|
|
255
|
-
allContexts =
|
|
248
|
+
allContexts = modelXbrl.contextsByDocument()
|
|
256
249
|
contextsWithImproperContent: list[ModelContext | None] = []
|
|
257
250
|
contextsWithPeriodTime: list[ModelContext | None] = []
|
|
258
251
|
contextsWithPeriodTimeZone: list[ModelContext | None] = []
|
|
@@ -395,9 +388,6 @@ class PluginValidationDataExtension(PluginData):
|
|
|
395
388
|
tupleElements=tupleElements,
|
|
396
389
|
)
|
|
397
390
|
|
|
398
|
-
@lru_cache(1)
|
|
399
|
-
def entityIdentifiersInDocument(self, modelXbrl: ModelXbrl) -> set[tuple[str, str]]:
|
|
400
|
-
return {context.entityIdentifier for context in modelXbrl.contexts.values()}
|
|
401
391
|
|
|
402
392
|
@lru_cache(1)
|
|
403
393
|
def factsByDocument(self, modelXbrl: ModelXbrl) -> dict[str, list[ModelFact]]:
|
|
@@ -192,44 +192,45 @@ class ValidationPluginExtension(ValidationPlugin):
|
|
|
192
192
|
jenvNamespace = 'https://www.nltaxonomie.nl/bw2-titel9/2024-12-31/bw2-titel9-cor'
|
|
193
193
|
kvkINamespace = 'https://www.nltaxonomie.nl/kvk/2024-12-31/kvk-cor'
|
|
194
194
|
nlTypesNamespace = None
|
|
195
|
-
rjNamespace =
|
|
195
|
+
rjNamespace = 'https://www.nltaxonomie.nl/rj/2024-12-31/rj-cor'
|
|
196
196
|
entrypointRoot = 'http://www.nltaxonomie.nl/kvk/2024-12-31/'
|
|
197
197
|
entrypoints = {entrypointRoot + e for e in [
|
|
198
198
|
'kvk-annual-report-other-gaap.xsd',
|
|
199
199
|
]}
|
|
200
200
|
else:
|
|
201
201
|
raise ValueError(f'Invalid NL disclosure system: {disclosureSystem}')
|
|
202
|
+
permissibleMandatoryFactsRootAbstracts=frozenset([
|
|
203
|
+
qname(kvkINamespace, 'AnnualReportFilingInformationTitle'),
|
|
204
|
+
]) if kvkINamespace else frozenset()
|
|
202
205
|
return PluginValidationDataExtension(
|
|
203
206
|
self.name,
|
|
204
|
-
chamberOfCommerceRegistrationNumberQn=qname(
|
|
205
|
-
documentAdoptionDateQn=qname(
|
|
206
|
-
documentAdoptionStatusQn=qname(
|
|
207
|
-
documentResubmissionUnsurmountableInaccuraciesQn=qname(
|
|
207
|
+
chamberOfCommerceRegistrationNumberQn=qname(jenvNamespace, 'ChamberOfCommerceRegistrationNumber'),
|
|
208
|
+
documentAdoptionDateQn=qname(jenvNamespace, 'DocumentAdoptionDate'),
|
|
209
|
+
documentAdoptionStatusQn=qname(jenvNamespace, 'DocumentAdoptionStatus'),
|
|
210
|
+
documentResubmissionUnsurmountableInaccuraciesQn=qname(kvkINamespace, 'DocumentResubmissionDueToUnsurmountableInaccuracies'),
|
|
208
211
|
entrypointRoot=entrypointRoot,
|
|
209
212
|
entrypoints=entrypoints,
|
|
210
|
-
financialReportingPeriodQn=qname(
|
|
211
|
-
financialReportingPeriodCurrentStartDateQn=qname(
|
|
212
|
-
financialReportingPeriodCurrentEndDateQn=qname(
|
|
213
|
-
financialReportingPeriodPreviousStartDateQn=qname(
|
|
214
|
-
financialReportingPeriodPreviousEndDateQn=qname(
|
|
215
|
-
formattedExplanationItemTypeQn=qname(
|
|
213
|
+
financialReportingPeriodQn=qname(jenvNamespace, 'FinancialReportingPeriod'),
|
|
214
|
+
financialReportingPeriodCurrentStartDateQn=qname(jenvNamespace, 'FinancialReportingPeriodCurrentStartDate'),
|
|
215
|
+
financialReportingPeriodCurrentEndDateQn=qname(jenvNamespace, 'FinancialReportingPeriodCurrentEndDate'),
|
|
216
|
+
financialReportingPeriodPreviousStartDateQn=qname(jenvNamespace, 'FinancialReportingPeriodPreviousStartDate'),
|
|
217
|
+
financialReportingPeriodPreviousEndDateQn=qname(jenvNamespace, 'FinancialReportingPeriodPreviousEndDate'),
|
|
218
|
+
formattedExplanationItemTypeQn=qname(nlTypesNamespace, 'formattedExplanationItemType') if nlTypesNamespace else None,
|
|
216
219
|
ifrsIdentifier = 'https://xbrl.ifrs.org',
|
|
217
|
-
permissibleGAAPRootAbstracts=frozenset([
|
|
218
|
-
qname(
|
|
219
|
-
qname(
|
|
220
|
-
qname(
|
|
221
|
-
qname(
|
|
222
|
-
qname(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
qname(
|
|
227
|
-
qname(
|
|
228
|
-
qname(
|
|
229
|
-
qname(
|
|
230
|
-
|
|
231
|
-
qname(f'{{{kvkINamespace}}}AnnualReportFilingInformationTitle'),
|
|
232
|
-
]),
|
|
220
|
+
permissibleGAAPRootAbstracts=permissibleMandatoryFactsRootAbstracts | frozenset([
|
|
221
|
+
qname(jenvNamespace, 'BalanceSheetTitle'),
|
|
222
|
+
qname(jenvNamespace, 'IncomeStatementTitle'),
|
|
223
|
+
qname(jenvNamespace, 'StatementOfComprehensiveIncomeTitle'),
|
|
224
|
+
qname(jenvNamespace, 'EquityStatementOfChangesTitle'),
|
|
225
|
+
qname(rjNamespace, 'CashFlowStatementTitle'),
|
|
226
|
+
]) if jenvNamespace and rjNamespace else frozenset(),
|
|
227
|
+
permissibleIFRSRootAbstracts=permissibleMandatoryFactsRootAbstracts | frozenset([
|
|
228
|
+
qname(ifrsNamespace, 'StatementOfFinancialPositionAbstract'),
|
|
229
|
+
qname(ifrsNamespace, 'IncomeStatementAbstract'),
|
|
230
|
+
qname(ifrsNamespace, 'StatementOfComprehensiveIncomeAbstract'),
|
|
231
|
+
qname(ifrsNamespace, 'StatementOfCashFlowsAbstract'),
|
|
232
|
+
qname(ifrsNamespace, 'StatementOfChangesInEquityAbstract'),
|
|
233
|
+
]) if ifrsNamespace else frozenset(),
|
|
233
234
|
textFormattingSchemaPath='sbr-text-formatting.xsd',
|
|
234
235
|
textFormattingWrapper='<formattedText xmlns="http://www.nltaxonomie.nl/2017/xbrl/sbr-text-formatting">{}</formattedText>',
|
|
235
236
|
)
|
|
@@ -179,7 +179,7 @@ def rule_fg_nl_05(
|
|
|
179
179
|
modelXbrl = val.modelXbrl
|
|
180
180
|
factsByDocument = pluginData.factsByDocument(modelXbrl)
|
|
181
181
|
unitsByDocument = pluginData.unitsByDocument(modelXbrl)
|
|
182
|
-
contextsByDocument =
|
|
182
|
+
contextsByDocument = modelXbrl.contextsByDocument()
|
|
183
183
|
|
|
184
184
|
for doc in modelXbrl.urlDocs.values():
|
|
185
185
|
if doc.type != ModelDocument.Type.INSTANCE:
|
|
@@ -15,7 +15,7 @@ from lxml import etree
|
|
|
15
15
|
from arelle import ModelDocument, XbrlConst, XmlUtil
|
|
16
16
|
from arelle.FileSource import openXmlFileStream
|
|
17
17
|
from arelle.ModelObject import ModelObject, ModelComment
|
|
18
|
-
from arelle.ModelValue import qname
|
|
18
|
+
from arelle.ModelValue import QName, qname
|
|
19
19
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
20
20
|
from arelle.typing import TypeGetText
|
|
21
21
|
from arelle.utils.PluginHooks import ValidationHook
|
|
@@ -771,6 +771,7 @@ def rule_fr_nl_5_11(
|
|
|
771
771
|
parser = etree.XMLParser(schema=schema)
|
|
772
772
|
|
|
773
773
|
invalidTypeFacts = []
|
|
774
|
+
assert isinstance(pluginData.formattedExplanationItemTypeQn, QName)
|
|
774
775
|
typeQname = pluginData.formattedExplanationItemTypeQn
|
|
775
776
|
for fact in val.modelXbrl.facts:
|
|
776
777
|
validType = fact.concept.instanceOfType(typeQname)
|
|
@@ -9,8 +9,6 @@ from collections.abc import Iterable
|
|
|
9
9
|
from datetime import date
|
|
10
10
|
from typing import Any, cast, TYPE_CHECKING
|
|
11
11
|
|
|
12
|
-
import zipfile
|
|
13
|
-
|
|
14
12
|
from lxml.etree import Element
|
|
15
13
|
|
|
16
14
|
from arelle.ModelDtsObject import ModelConcept, ModelLink, ModelResource, ModelType
|
|
@@ -82,7 +80,7 @@ def rule_nl_kvk_3_1_1_1(
|
|
|
82
80
|
NL-KVK.3.1.1.1: xbrli:identifier content to match KVK number format that must consist of 8 consecutive digits;
|
|
83
81
|
first two digits must not be '00'.
|
|
84
82
|
"""
|
|
85
|
-
entityIdentifierValues =
|
|
83
|
+
entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
|
|
86
84
|
for entityId in entityIdentifierValues:
|
|
87
85
|
if not XBRLI_IDENTIFIER_PATTERN.match(entityId[1]):
|
|
88
86
|
yield Validation.error(
|
|
@@ -107,7 +105,7 @@ def rule_nl_kvk_3_1_1_2(
|
|
|
107
105
|
"""
|
|
108
106
|
NL-KVK.3.1.1.2: Scheme attribute of xbrli:identifier must be http://www.kvk.nl/kvk-id.
|
|
109
107
|
"""
|
|
110
|
-
entityIdentifierValues =
|
|
108
|
+
entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
|
|
111
109
|
for entityId in entityIdentifierValues:
|
|
112
110
|
if XBRLI_IDENTIFIER_SCHEMA != entityId[0]:
|
|
113
111
|
yield Validation.error(
|
|
@@ -220,7 +218,7 @@ def rule_nl_kvk_3_1_4_1 (
|
|
|
220
218
|
"""
|
|
221
219
|
NL-KVK.3.1.4.1: All entity identifiers and schemes must have identical content.
|
|
222
220
|
"""
|
|
223
|
-
entityIdentifierValues =
|
|
221
|
+
entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
|
|
224
222
|
if len(entityIdentifierValues) >1:
|
|
225
223
|
yield Validation.error(
|
|
226
224
|
codes='NL.NL-KVK-RTS_Annex_IV_Par_1_G3-1-4_1.multipleIdentifiers',
|
|
@@ -1582,7 +1580,7 @@ def rule_nl_kvk_4_4_4_1(
|
|
|
1582
1580
|
**kwargs: Any,
|
|
1583
1581
|
) -> Iterable[Validation]:
|
|
1584
1582
|
"""
|
|
1585
|
-
NL-KVK.4.4.
|
|
1583
|
+
NL-KVK.4.4.4.1: Duplicated line items in the presentation tree of extension taxonomy SHOULD use preferred labels on presentation links.
|
|
1586
1584
|
"""
|
|
1587
1585
|
warnings = set()
|
|
1588
1586
|
for ELR in val.modelXbrl.relationshipSet(XbrlConst.parentChild).linkRoleUris:
|
|
@@ -1820,9 +1818,9 @@ def rule_nl_kvk_RTS_Annex_II_Par_1_RTS_Annex_IV_par_7(
|
|
|
1820
1818
|
for ELR in val.modelXbrl.relationshipSet(parentChild).linkRoleUris:
|
|
1821
1819
|
relSet = val.modelXbrl.relationshipSet(parentChild, ELR)
|
|
1822
1820
|
for rootConcept in relSet.rootConcepts:
|
|
1823
|
-
if relSet.fromModelObject(rootConcept):
|
|
1824
|
-
if
|
|
1825
|
-
warnings.append(
|
|
1821
|
+
if rels := relSet.fromModelObject(rootConcept):
|
|
1822
|
+
if rootConcept.qname not in permissibleAbstracts:
|
|
1823
|
+
warnings.append(rels[0])
|
|
1826
1824
|
if len(warnings) > 0:
|
|
1827
1825
|
yield Validation.warning(
|
|
1828
1826
|
codes='NL.NL-KVK.RTS_Annex_II_Par_1_RTS_Annex_IV_par_7.missingRelevantPlaceholder',
|
|
@@ -45,11 +45,11 @@ arelle/ModelRelationshipSet.py,sha256=jlLqEnd0KrLjpRUhDzFLgMPsRmyOwfgl1w13yW3flL
|
|
|
45
45
|
arelle/ModelRenderingObject.py,sha256=iPhSUlSBG-FLzAfIdUW06UZDgTCaZJ4K2mxvAtSe2BU,76021
|
|
46
46
|
arelle/ModelRssItem.py,sha256=GzFkmluOlFsVcrxn9HAyOAcuE7rcHUOGkp4Q6F2IlT8,7713
|
|
47
47
|
arelle/ModelRssObject.py,sha256=xjuwyJ8pU5sQmNPJFQakDEEnujZg2bMCTaj3zVezHL8,992
|
|
48
|
-
arelle/ModelTestcaseObject.py,sha256=
|
|
48
|
+
arelle/ModelTestcaseObject.py,sha256=2hFrl1tdDAxPZpZCEJdYUzti-HFLGgDgCNp6lEBPvqs,22616
|
|
49
49
|
arelle/ModelValue.py,sha256=0sr7njFjGI2W3Bct2dxf2LoG_fLerHQouQtM0v0ZY2E,39573
|
|
50
50
|
arelle/ModelVersObject.py,sha256=cPD1IzhkCfuV1eMgVFWes88DH_6WkUj5kj7sgGF2M0I,26062
|
|
51
51
|
arelle/ModelVersReport.py,sha256=bXEA9K3qkH57aABn5l-m3CTY0FAcF1yX6O4fo-URjl8,73326
|
|
52
|
-
arelle/ModelXbrl.py,sha256=
|
|
52
|
+
arelle/ModelXbrl.py,sha256=fN2yLWfsXovPeU2fmUToQTnSJQeX3Nl3y9nmtt3Egeg,72598
|
|
53
53
|
arelle/PackageManager.py,sha256=BvPExMcxh8rHMxogOag-PGbX6vXdhCiXAHcDLA6Ypsc,32592
|
|
54
54
|
arelle/PluginManager.py,sha256=foSgWvRI1Ret-6KVRQMFSv4RtpEf_0UB7468N_NjPGU,42116
|
|
55
55
|
arelle/PluginUtils.py,sha256=0vFQ29wVVpU0cTY3YOBL6FhNQhhCTwShBH4qTJGLnvc,2426
|
|
@@ -114,7 +114,7 @@ arelle/ViewWinVersReport.py,sha256=aYfsOgynVZpMzl6f2EzQCBLzdihYGycwb5SiTghkgMQ,9
|
|
|
114
114
|
arelle/ViewWinXml.py,sha256=4ZGKtjaoCwU9etKYm9ZAS7jSmUxba1rqNEdv0OIyjTY,1250
|
|
115
115
|
arelle/WatchRss.py,sha256=5Ih4igH2MM4hpOuAXy9eO0QAyZ7jZR3S5bPzo2sdFpw,14097
|
|
116
116
|
arelle/WebCache.py,sha256=HlF4vfjxO0bSFHqMPfjnmkrzc7RK9XT714a7g3XFTDY,45192
|
|
117
|
-
arelle/XbrlConst.py,sha256=
|
|
117
|
+
arelle/XbrlConst.py,sha256=U8YqMd-YKz-7WJrRDu3YzCkj_BG4MP3mdm0ED9sJ4c8,58456
|
|
118
118
|
arelle/XbrlUtil.py,sha256=s2Vmrh-sZI5TeuqsziKignOc3ao-uUgnCNoelP4dDj0,9212
|
|
119
119
|
arelle/XhtmlValidate.py,sha256=0gtm7N-kXK0RB5o3c1AQXjfFuRp1w2fKZZAeyruNANw,5727
|
|
120
120
|
arelle/XmlUtil.py,sha256=1VToOOylF8kbEorEdZLThmq35j9bmuF_DS2q9NthnHU,58774
|
|
@@ -123,7 +123,7 @@ arelle/XmlValidateConst.py,sha256=U_wN0Q-nWKwf6dKJtcu_83FXPn9c6P8JjzGA5b0w7P0,33
|
|
|
123
123
|
arelle/XmlValidateParticles.py,sha256=Mn6vhFl0ZKC_vag1mBwn1rH_x2jmlusJYqOOuxFPO2k,9231
|
|
124
124
|
arelle/XmlValidateSchema.py,sha256=6frtZOc1Yrx_5yYF6V6oHbScnglWrVbWr6xW4EHtLQI,7428
|
|
125
125
|
arelle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
126
|
-
arelle/_version.py,sha256
|
|
126
|
+
arelle/_version.py,sha256=-XXBu4KjzmMOb27ISFZtxgU868vA14VkfmOyupc5LJw,515
|
|
127
127
|
arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
|
|
128
128
|
arelle/api/Session.py,sha256=27HVuK3Bz1_21l4_RLn1IQg6v0MNsUEYrHajymyWwxI,7429
|
|
129
129
|
arelle/archive/CustomLogger.py,sha256=v_JXOCQLDZcfaFWzxC9FRcEf9tQi4rCI4Sx7jCuAVQI,1231
|
|
@@ -402,9 +402,9 @@ arelle/plugin/validate/EDINET/__init__.py,sha256=ew9Rc2qJe5d3XvOOFzhX6MfzxNUtxIY
|
|
|
402
402
|
arelle/plugin/validate/EDINET/resources/config.xml,sha256=GmLcW7UIj5koXJkN19P6Nq5EZJcs6gKQLQ5f2V6u78w,614
|
|
403
403
|
arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml,sha256=997I3RGTLg5OY3vn5hQxVFAAxOmDSOYpuyQe6VnWSY0,16285
|
|
404
404
|
arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
405
|
-
arelle/plugin/validate/EDINET/rules/edinet.py,sha256=
|
|
406
|
-
arelle/plugin/validate/EDINET/rules/frta.py,sha256=
|
|
407
|
-
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=
|
|
405
|
+
arelle/plugin/validate/EDINET/rules/edinet.py,sha256=PKbylqzhbi2ItMCW-eliaQysCzYg_rAkWzwRJmX1RtQ,4180
|
|
406
|
+
arelle/plugin/validate/EDINET/rules/frta.py,sha256=N0YglHYZuLD2IuwE26viR2ViwUYjneBuMFU9vlrS0aQ,7616
|
|
407
|
+
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=SaVUW1cvrwRSjoq_W97HGCk-3ccE7MKfLut3K8yuUQ8,16657
|
|
408
408
|
arelle/plugin/validate/EDINET/rules/upload.py,sha256=HZ-9Gk6WtIichTGcSsSGIrMXNgsgJYQYwfUKeLs1XWU,20369
|
|
409
409
|
arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
|
|
410
410
|
arelle/plugin/validate/ESEF/Dimensions.py,sha256=MOJM7vwNPEmV5cu-ZzPrhx3347ZvxgD6643OB2HRnIk,10597
|
|
@@ -417,23 +417,23 @@ arelle/plugin/validate/ESEF/ESEF_2021/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
417
417
|
arelle/plugin/validate/ESEF/ESEF_Current/DTS.py,sha256=epp-PBh1NJzQqgxUE6C468HmoDc2w3j54rMwfiOAry4,29334
|
|
418
418
|
arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py,sha256=XMFlRc9X-dwMkyaEMWxmNWnTRBlFjzpA8JsyMWknzvs,75251
|
|
419
419
|
arelle/plugin/validate/ESEF/ESEF_Current/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
420
|
-
arelle/plugin/validate/ESEF/resources/authority-validations.json,sha256=
|
|
420
|
+
arelle/plugin/validate/ESEF/resources/authority-validations.json,sha256=bR0ZMpiQL9LqiyzrjhAGMDLEHBHimsDuDu9SQY5xofA,15503
|
|
421
421
|
arelle/plugin/validate/ESEF/resources/config.xml,sha256=t3STU_-QYM7Ay8YwZRPapnohiWVWhjfr4L2Rjx9xN9U,3902
|
|
422
422
|
arelle/plugin/validate/FERC/__init__.py,sha256=V4fXcFKBsjFFPs9_1NhvDjWpEQCoQM0tRQMS0I1Ua7U,11462
|
|
423
423
|
arelle/plugin/validate/FERC/config.xml,sha256=bn9b8eCqJA1J62rYq1Nz85wJrMGAahVmmnIUQZyerjo,1919
|
|
424
424
|
arelle/plugin/validate/FERC/resources/ferc-utr.xml,sha256=OCRj9IUpdXATCBXKbB71apYx9kxcNtZW-Hq4s-avsRY,2663
|
|
425
425
|
arelle/plugin/validate/NL/DisclosureSystems.py,sha256=urRmYJ8RnGPlTgSVKW7zGN4_4CtL3OVKlcI3LwTpBz4,561
|
|
426
426
|
arelle/plugin/validate/NL/LinkbaseType.py,sha256=BwRQl4XZFFCopufC2FEMLhYENNTk2JUWVQvnIUsaqtI,3108
|
|
427
|
-
arelle/plugin/validate/NL/PluginValidationDataExtension.py,sha256=
|
|
428
|
-
arelle/plugin/validate/NL/ValidationPluginExtension.py,sha256=
|
|
427
|
+
arelle/plugin/validate/NL/PluginValidationDataExtension.py,sha256=HB6jIGhsQFE3GKI8FpD96g3cP6IWj3ij4dE_xmSkmMA,34235
|
|
428
|
+
arelle/plugin/validate/NL/ValidationPluginExtension.py,sha256=h6CjGJJkE8YqrzPiA8uNaCzn_P6HspH-6ja89tLCXxY,17978
|
|
429
429
|
arelle/plugin/validate/NL/__init__.py,sha256=W-SHohiAWM7Yi77gAbt-D3vvZNAB5s1j16mHCTFta6w,3158
|
|
430
430
|
arelle/plugin/validate/NL/resources/config.xml,sha256=qBE6zywFSmemBSWonuTII5iuOCUlNb1nvkpMbsZb5PM,1853
|
|
431
431
|
arelle/plugin/validate/NL/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
432
432
|
arelle/plugin/validate/NL/rules/br_kvk.py,sha256=0SwKieWzTDm3YMsXPS6zTdgbk7_Z9CzqRkRmCRz1OiQ,15789
|
|
433
|
-
arelle/plugin/validate/NL/rules/fg_nl.py,sha256=
|
|
433
|
+
arelle/plugin/validate/NL/rules/fg_nl.py,sha256=OJF2EYx4KDTdNggHiw5Trq5S5g7WGpbb7YvO6_IrrGU,10704
|
|
434
434
|
arelle/plugin/validate/NL/rules/fr_kvk.py,sha256=kYqXt45S6eM32Yg9ii7pUhOMfJaHurgYqQ73FyQALs8,8171
|
|
435
|
-
arelle/plugin/validate/NL/rules/fr_nl.py,sha256
|
|
436
|
-
arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=
|
|
435
|
+
arelle/plugin/validate/NL/rules/fr_nl.py,sha256=bKY3vLInnZFNwdGXp-sUTvjgRi3dK3n2GiJ0-GlAsdY,31503
|
|
436
|
+
arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=l_pxjaj9kyFKl6uYYDHQghuzKxAUy_P8Lko7lbz-wJc,90189
|
|
437
437
|
arelle/plugin/validate/ROS/DisclosureSystems.py,sha256=rJ81mwQDYTi6JecFZ_zhqjjz3VNQRgjHNSh0wcQWAQE,18
|
|
438
438
|
arelle/plugin/validate/ROS/PluginValidationDataExtension.py,sha256=IV7ILhNvgKwQXqbpSA6HRNt9kEnejCyMADI3wyyIgk0,4036
|
|
439
439
|
arelle/plugin/validate/ROS/ValidationPluginExtension.py,sha256=FBhEp8t396vGdvCbMEimfcxmGiGnhXMen-yVLWnkFaI,758
|
|
@@ -756,9 +756,9 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
|
|
|
756
756
|
arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
757
757
|
arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
758
758
|
arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
|
|
759
|
-
arelle_release-2.37.
|
|
760
|
-
arelle_release-2.37.
|
|
761
|
-
arelle_release-2.37.
|
|
762
|
-
arelle_release-2.37.
|
|
763
|
-
arelle_release-2.37.
|
|
764
|
-
arelle_release-2.37.
|
|
759
|
+
arelle_release-2.37.38.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
|
|
760
|
+
arelle_release-2.37.38.dist-info/METADATA,sha256=FHHaBwTHXeDmmnXHgmKzkl3Cs-Y8btdXUJCrodSOXSk,9137
|
|
761
|
+
arelle_release-2.37.38.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
762
|
+
arelle_release-2.37.38.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
|
|
763
|
+
arelle_release-2.37.38.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
|
|
764
|
+
arelle_release-2.37.38.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|