arelle-release 2.37.48__py3-none-any.whl → 2.37.49__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/_version.py +2 -2
- arelle/plugin/validate/EDINET/Constants.py +6 -0
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +134 -7
- arelle/plugin/validate/EDINET/Statement.py +139 -0
- arelle/plugin/validate/EDINET/rules/contexts.py +5 -10
- arelle/plugin/validate/EDINET/rules/edinet.py +89 -51
- arelle/plugin/validate/EDINET/rules/gfm.py +41 -0
- {arelle_release-2.37.48.dist-info → arelle_release-2.37.49.dist-info}/METADATA +3 -1
- {arelle_release-2.37.48.dist-info → arelle_release-2.37.49.dist-info}/RECORD +13 -12
- {arelle_release-2.37.48.dist-info → arelle_release-2.37.49.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.48.dist-info → arelle_release-2.37.49.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.48.dist-info → arelle_release-2.37.49.dist-info}/licenses/LICENSE.md +0 -0
- {arelle_release-2.37.48.dist-info → arelle_release-2.37.49.dist-info}/top_level.txt +0 -0
arelle/_version.py
CHANGED
|
@@ -5,6 +5,11 @@ from enum import Enum
|
|
|
5
5
|
|
|
6
6
|
from arelle.ModelValue import qname
|
|
7
7
|
|
|
8
|
+
class AccountingStandard(Enum):
|
|
9
|
+
IFRS = 'IFRS'
|
|
10
|
+
JAPAN_GAAP = 'Japan GAAP'
|
|
11
|
+
US_GAAP = 'US GAAP'
|
|
12
|
+
|
|
8
13
|
class FormType(Enum):
|
|
9
14
|
FORM_2_4 = '第二号の四様式'
|
|
10
15
|
FORM_2_7 = '第二号の七様式'
|
|
@@ -22,3 +27,4 @@ qnEdinetManifestIxbrl = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest
|
|
|
22
27
|
qnEdinetManifestList = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}list")
|
|
23
28
|
qnEdinetManifestTitle = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}title")
|
|
24
29
|
qnEdinetManifestTocComposition = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}tocComposition")
|
|
30
|
+
xhtmlDtdExtension = "xhtml1-strict-ix.dtd"
|
|
@@ -3,15 +3,19 @@ See COPYRIGHT.md for copyright information.
|
|
|
3
3
|
"""
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
from collections import defaultdict
|
|
7
7
|
from dataclasses import dataclass
|
|
8
|
+
from decimal import Decimal
|
|
8
9
|
from functools import lru_cache
|
|
9
|
-
from
|
|
10
|
+
from operator import attrgetter
|
|
11
|
+
from typing import Callable, Hashable, Iterable, cast
|
|
10
12
|
|
|
11
13
|
import regex
|
|
12
14
|
|
|
15
|
+
from arelle.LinkbaseType import LinkbaseType
|
|
13
16
|
from arelle.ModelDocument import Type as ModelDocumentType
|
|
14
|
-
from arelle.
|
|
17
|
+
from arelle.ModelDtsObject import ModelConcept
|
|
18
|
+
from arelle.ModelInstanceObject import ModelFact, ModelUnit, ModelContext
|
|
15
19
|
from arelle.ModelObject import ModelObject
|
|
16
20
|
from arelle.ModelValue import QName, qname
|
|
17
21
|
from arelle.ModelXbrl import ModelXbrl
|
|
@@ -23,18 +27,23 @@ from arelle.utils.PluginData import PluginData
|
|
|
23
27
|
from .Constants import CORPORATE_FORMS
|
|
24
28
|
from .ControllerPluginData import ControllerPluginData
|
|
25
29
|
from .ManifestInstance import ManifestInstance
|
|
30
|
+
from .Statement import Statement, STATEMENTS, BalanceSheet, StatementInstance, StatementType
|
|
26
31
|
|
|
27
32
|
_: TypeGetText
|
|
28
33
|
|
|
29
34
|
|
|
35
|
+
_DEBIT_QNAME_PATTERN = regex.compile('.*(Liability|Liabilities|Equity)')
|
|
36
|
+
|
|
37
|
+
|
|
30
38
|
@dataclass
|
|
31
39
|
class PluginValidationDataExtension(PluginData):
|
|
40
|
+
accountingStandardsDeiQn: QName
|
|
32
41
|
assetsIfrsQn: QName
|
|
42
|
+
consolidatedOrNonConsolidatedAxisQn: QName
|
|
33
43
|
documentTypeDeiQn: QName
|
|
34
44
|
jpcrpEsrFilingDateCoverPageQn: QName
|
|
35
45
|
jpcrpFilingDateCoverPageQn: QName
|
|
36
46
|
jpspsFilingDateCoverPageQn: QName
|
|
37
|
-
liabilitiesAndEquityIfrsQn: QName
|
|
38
47
|
nonConsolidatedMemberQn: QName
|
|
39
48
|
ratioOfFemaleDirectorsAndOtherOfficersQn: QName
|
|
40
49
|
|
|
@@ -50,12 +59,13 @@ class PluginValidationDataExtension(PluginData):
|
|
|
50
59
|
jpigpNamespace = "http://disclosure.edinet-fsa.go.jp/taxonomy/jpigp/2024-11-01/jpigp_cor"
|
|
51
60
|
jppfsNamespace = "http://disclosure.edinet-fsa.go.jp/taxonomy/jppfs/2024-11-01/jppfs_cor"
|
|
52
61
|
jpspsNamespace = 'http://disclosure.edinet-fsa.go.jp/taxonomy/jpsps/2024-11-01/jpsps_cor'
|
|
62
|
+
self.accountingStandardsDeiQn = qname(jpdeiNamespace, 'AccountingStandardsDEI')
|
|
53
63
|
self.assetsIfrsQn = qname(jpigpNamespace, 'AssetsIFRS')
|
|
64
|
+
self.consolidatedOrNonConsolidatedAxisQn = qname(jppfsNamespace, 'ConsolidatedOrNonConsolidatedAxis')
|
|
54
65
|
self.documentTypeDeiQn = qname(jpdeiNamespace, 'DocumentTypeDEI')
|
|
55
66
|
self.jpcrpEsrFilingDateCoverPageQn = qname(jpcrpEsrNamespace, 'FilingDateCoverPage')
|
|
56
67
|
self.jpcrpFilingDateCoverPageQn = qname(jpcrpNamespace, 'FilingDateCoverPage')
|
|
57
68
|
self.jpspsFilingDateCoverPageQn = qname(jpspsNamespace, 'FilingDateCoverPage')
|
|
58
|
-
self.liabilitiesAndEquityIfrsQn = qname(jpigpNamespace, "LiabilitiesAndEquityIFRS")
|
|
59
69
|
self.nonConsolidatedMemberQn = qname(jppfsNamespace, "NonConsolidatedMember")
|
|
60
70
|
self.ratioOfFemaleDirectorsAndOtherOfficersQn = qname(jpcrpNamespace, "RatioOfFemaleDirectorsAndOtherOfficers")
|
|
61
71
|
|
|
@@ -65,6 +75,27 @@ class PluginValidationDataExtension(PluginData):
|
|
|
65
75
|
def __hash__(self) -> int:
|
|
66
76
|
return id(self)
|
|
67
77
|
|
|
78
|
+
@lru_cache(1)
|
|
79
|
+
def _contextMatchesStatement(self, modelXbrl: ModelXbrl, contextId: str, statement: Statement) -> bool:
|
|
80
|
+
"""
|
|
81
|
+
:return: Whether the context's facts are applicable to the given statement.
|
|
82
|
+
"""
|
|
83
|
+
if 'Interim' in contextId:
|
|
84
|
+
# valid06.zip suggests "interim"" contexts are not considered for balance sheets.
|
|
85
|
+
return False
|
|
86
|
+
context = modelXbrl.contexts[contextId]
|
|
87
|
+
if not all(dimQn == self.consolidatedOrNonConsolidatedAxisQn for dimQn in context.qnameDims):
|
|
88
|
+
return False
|
|
89
|
+
memberValue = context.dimMemberQname(self.consolidatedOrNonConsolidatedAxisQn, includeDefaults=True)
|
|
90
|
+
contextIsConsolidated = memberValue != self.nonConsolidatedMemberQn
|
|
91
|
+
return bool(statement.isConsolidated == contextIsConsolidated)
|
|
92
|
+
|
|
93
|
+
def _isDebitConcept(self, concept: ModelConcept) -> bool:
|
|
94
|
+
"""
|
|
95
|
+
:return: Whether the given concept is a debit concept.
|
|
96
|
+
"""
|
|
97
|
+
return bool(_DEBIT_QNAME_PATTERN.match(concept.qname.localName))
|
|
98
|
+
|
|
68
99
|
@lru_cache(1)
|
|
69
100
|
def isCorporateForm(self, modelXbrl: ModelXbrl) -> bool:
|
|
70
101
|
documentTypes = self.getDocumentTypes(modelXbrl)
|
|
@@ -72,6 +103,79 @@ class PluginValidationDataExtension(PluginData):
|
|
|
72
103
|
return True
|
|
73
104
|
return False
|
|
74
105
|
|
|
106
|
+
|
|
107
|
+
def getBalanceSheets(self, modelXbrl: ModelXbrl, statement: Statement) -> list[BalanceSheet]:
|
|
108
|
+
"""
|
|
109
|
+
:return: Balance sheet data for each context/unit pairing the given statement.
|
|
110
|
+
"""
|
|
111
|
+
balanceSheets: list[BalanceSheet] = []
|
|
112
|
+
if statement.roleUri not in modelXbrl.roleTypes:
|
|
113
|
+
return balanceSheets
|
|
114
|
+
if statement.statementType not in (
|
|
115
|
+
StatementType.BALANCE_SHEET,
|
|
116
|
+
StatementType.STATEMENT_OF_FINANCIAL_POSITION
|
|
117
|
+
):
|
|
118
|
+
return balanceSheets
|
|
119
|
+
|
|
120
|
+
relSet = modelXbrl.relationshipSet(
|
|
121
|
+
tuple(LinkbaseType.CALCULATION.getArcroles()),
|
|
122
|
+
linkrole=statement.roleUri
|
|
123
|
+
)
|
|
124
|
+
rootConcepts = relSet.rootConcepts
|
|
125
|
+
if len(rootConcepts) == 0:
|
|
126
|
+
return balanceSheets
|
|
127
|
+
|
|
128
|
+
# GFM 1.2.7 and 1.2.10 asserts no duplicate contexts and units, respectively,
|
|
129
|
+
# so context and unit IDs can be used as a key.
|
|
130
|
+
factsByContextIdAndUnitId = self.getFactsByContextAndUnit(
|
|
131
|
+
modelXbrl,
|
|
132
|
+
attrgetter("id"),
|
|
133
|
+
attrgetter("id"),
|
|
134
|
+
tuple(concept.qname for concept in rootConcepts)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
for (contextId, unitId), facts in factsByContextIdAndUnitId.items():
|
|
138
|
+
if not self._contextMatchesStatement(modelXbrl, contextId, statement):
|
|
139
|
+
continue
|
|
140
|
+
assetSum = Decimal(0)
|
|
141
|
+
liabilitiesAndEquitySum = Decimal(0)
|
|
142
|
+
for fact in facts:
|
|
143
|
+
if isinstance(fact.xValue, float):
|
|
144
|
+
value = Decimal(fact.xValue)
|
|
145
|
+
else:
|
|
146
|
+
value = cast(Decimal, fact.xValue)
|
|
147
|
+
if self._isDebitConcept(fact.concept):
|
|
148
|
+
liabilitiesAndEquitySum += value
|
|
149
|
+
else:
|
|
150
|
+
assetSum += value
|
|
151
|
+
balanceSheets.append(
|
|
152
|
+
BalanceSheet(
|
|
153
|
+
assetsTotal=assetSum,
|
|
154
|
+
contextId=str(contextId),
|
|
155
|
+
facts=facts,
|
|
156
|
+
liabilitiesAndEquityTotal=liabilitiesAndEquitySum,
|
|
157
|
+
unitId=str(unitId),
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
return balanceSheets
|
|
161
|
+
|
|
162
|
+
@lru_cache(1)
|
|
163
|
+
def getStatementInstance(self, modelXbrl: ModelXbrl, statement: Statement) -> StatementInstance | None:
|
|
164
|
+
if statement.roleUri not in modelXbrl.roleTypes:
|
|
165
|
+
return None
|
|
166
|
+
return StatementInstance(
|
|
167
|
+
balanceSheets=self.getBalanceSheets(modelXbrl, statement),
|
|
168
|
+
statement=statement,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
@lru_cache(1)
|
|
172
|
+
def getStatementInstances(self, modelXbrl: ModelXbrl) -> list[StatementInstance]:
|
|
173
|
+
return [
|
|
174
|
+
statementInstance
|
|
175
|
+
for statement in STATEMENTS
|
|
176
|
+
if (statementInstance := self.getStatementInstance(modelXbrl, statement)) is not None
|
|
177
|
+
]
|
|
178
|
+
|
|
75
179
|
@lru_cache(1)
|
|
76
180
|
def getDeduplicatedFacts(self, modelXbrl: ModelXbrl) -> list[ModelFact]:
|
|
77
181
|
return getDeduplicatedFacts(modelXbrl, DeduplicationType.CONSISTENT_PAIRS)
|
|
@@ -85,6 +189,24 @@ class PluginValidationDataExtension(PluginData):
|
|
|
85
189
|
documentTypes.add(fact.textValue)
|
|
86
190
|
return documentTypes
|
|
87
191
|
|
|
192
|
+
def getFactsByContextAndUnit(
|
|
193
|
+
self, modelXbrl: ModelXbrl,
|
|
194
|
+
getContextKey: Callable[[ModelContext], Hashable],
|
|
195
|
+
getUnitKey: Callable[[ModelUnit], Hashable],
|
|
196
|
+
qnames: tuple[QName, ...] | None = None,
|
|
197
|
+
) -> dict[tuple[Hashable, Hashable], list[ModelFact]]:
|
|
198
|
+
deduplicatedFacts = self.getDeduplicatedFacts(modelXbrl)
|
|
199
|
+
getFactsByContextAndUnit = defaultdict(list)
|
|
200
|
+
for fact in deduplicatedFacts:
|
|
201
|
+
if qnames is not None and fact.qname not in qnames:
|
|
202
|
+
continue
|
|
203
|
+
if fact.context is None or fact.unit is None:
|
|
204
|
+
continue
|
|
205
|
+
contextKey = getContextKey(fact.context)
|
|
206
|
+
unitKey = getUnitKey(fact.unit)
|
|
207
|
+
getFactsByContextAndUnit[(contextKey, unitKey)].append(fact)
|
|
208
|
+
return dict(getFactsByContextAndUnit)
|
|
209
|
+
|
|
88
210
|
@lru_cache(1)
|
|
89
211
|
def getFootnoteLinkElements(self, modelXbrl: ModelXbrl) -> list[ModelObject | LinkPrototype]:
|
|
90
212
|
# TODO: Consolidate with similar implementations in EDGAR and FERC
|
|
@@ -113,8 +235,13 @@ class PluginValidationDataExtension(PluginData):
|
|
|
113
235
|
return controllerPluginData.matchManifestInstance(modelXbrl.ixdsDocUrls)
|
|
114
236
|
|
|
115
237
|
def hasValidNonNilFact(self, modelXbrl: ModelXbrl, qname: QName) -> bool:
|
|
116
|
-
|
|
117
|
-
return any(fact.xValid >= VALID and not fact.isNil for fact in requiredFacts)
|
|
238
|
+
return any(fact is not None for fact in self.iterValidNonNilFacts(modelXbrl, qname))
|
|
118
239
|
|
|
119
240
|
def isStandardTaxonomyUrl(self, uri: str, modelXbrl: ModelXbrl) -> bool:
|
|
120
241
|
return modelXbrl.modelManager.disclosureSystem.hrefValidForDisclosureSystem(uri)
|
|
242
|
+
|
|
243
|
+
def iterValidNonNilFacts(self, modelXbrl: ModelXbrl, qname: QName) -> Iterable[ModelFact]:
|
|
244
|
+
facts = modelXbrl.factsByQname.get(qname, set())
|
|
245
|
+
for fact in facts:
|
|
246
|
+
if fact.xValid >= VALID and not fact.isNil:
|
|
247
|
+
yield fact
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
from regex import regex
|
|
6
|
+
|
|
7
|
+
from arelle.ModelInstanceObject import ModelFact
|
|
8
|
+
|
|
9
|
+
CONSOLIDATED_ROLE_URI_PATTERN = regex.compile(r'.*rol_[\w]*Consolidated')
|
|
10
|
+
|
|
11
|
+
STATEMENT_ROLE_URIS = frozenset([
|
|
12
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterPeriodConsolidatedStatementOfComprehensiveIncomeIFRS',
|
|
13
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterPeriodConsolidatedStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
14
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterPeriodConsolidatedStatementOfProfitOrLossIFRS',
|
|
15
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterPeriodStatementOfComprehensiveIncomeIFRS',
|
|
16
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterPeriodStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
17
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterPeriodStatementOfProfitOrLossIFRS',
|
|
18
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyConsolidatedStatementOfCashFlowsIFRS',
|
|
19
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyConsolidatedStatementOfChangesInEquityIFRS',
|
|
20
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyConsolidatedStatementOfComprehensiveIncomeIFRS',
|
|
21
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyConsolidatedStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
22
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyConsolidatedStatementOfFinancialPositionIFRS',
|
|
23
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyConsolidatedStatementOfProfitOrLossIFRS',
|
|
24
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyStatementOfCashFlowsIFRS',
|
|
25
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyStatementOfChangesInEquityIFRS',
|
|
26
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyStatementOfComprehensiveIncomeIFRS',
|
|
27
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
28
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyStatementOfFinancialPositionIFRS',
|
|
29
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedQuarterlyStatementOfProfitOrLossIFRS',
|
|
30
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualConsolidatedStatementOfCashFlowsIFRS',
|
|
31
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualConsolidatedStatementOfChangesInEquityIFRS',
|
|
32
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualConsolidatedStatementOfComprehensiveIncomeIFRS',
|
|
33
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualConsolidatedStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
34
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualConsolidatedStatementOfFinancialPositionIFRS',
|
|
35
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualConsolidatedStatementOfProfitOrLossIFRS',
|
|
36
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualStatementOfCashFlowsIFRS',
|
|
37
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualStatementOfChangesInEquityIFRS',
|
|
38
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualStatementOfComprehensiveIncomeIFRS',
|
|
39
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
40
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualStatementOfFinancialPositionIFRS',
|
|
41
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedSemiAnnualStatementOfProfitOrLossIFRS',
|
|
42
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedYearToQuarterEndConsolidatedStatementOfComprehensiveIncomeIFRS',
|
|
43
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedYearToQuarterEndConsolidatedStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
44
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedYearToQuarterEndConsolidatedStatementOfProfitOrLossIFRS',
|
|
45
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedYearToQuarterEndStatementOfComprehensiveIncomeIFRS',
|
|
46
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedYearToQuarterEndStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
47
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_CondensedYearToQuarterEndStatementOfProfitOrLossIFRS',
|
|
48
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_ConsolidatedStatementOfCashFlowsIFRS',
|
|
49
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_ConsolidatedStatementOfChangesInEquityIFRS',
|
|
50
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_ConsolidatedStatementOfComprehensiveIncomeIFRS',
|
|
51
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_ConsolidatedStatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
52
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_ConsolidatedStatementOfFinancialPositionIFRS',
|
|
53
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_ConsolidatedStatementOfProfitOrLossIFRS',
|
|
54
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_StatementOfCashFlowsIFRS',
|
|
55
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_StatementOfChangesInEquityIFRS',
|
|
56
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_StatementOfComprehensiveIncomeIFRS',
|
|
57
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_StatementOfComprehensiveIncomeSingleStatementIFRS',
|
|
58
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_StatementOfFinancialPositionIFRS',
|
|
59
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_StatementOfProfitOrLossIFRS',
|
|
60
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_std_ConsolidatedStatementOfCashFlowsIFRS',
|
|
61
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_std_ConsolidatedStatementOfChangesInEquityIFRS',
|
|
62
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_std_ConsolidatedStatementOfComprehensiveIncomeIFRS',
|
|
63
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_std_ConsolidatedStatementOfFinancialPositionIFRS',
|
|
64
|
+
'http://disclosure.edinet-fsa.go.jp/role/jpigp/rol_std_ConsolidatedStatementOfProfitOrLossIFRS',
|
|
65
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_BalanceSheet',
|
|
66
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_ConsolidatedBalanceSheet',
|
|
67
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_QuarterlyBalanceSheet',
|
|
68
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_QuarterlyConsolidatedBalanceSheet',
|
|
69
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_SemiAnnualBalanceSheet',
|
|
70
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_SemiAnnualConsolidatedBalanceSheet',
|
|
71
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_Type1SemiAnnualBalanceSheet',
|
|
72
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_Type1SemiAnnualConsolidatedBalanceSheet',
|
|
73
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_std_BalanceSheet',
|
|
74
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_std_ConsolidatedBalanceSheet',
|
|
75
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_std_QuarterlyBalanceSheet',
|
|
76
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_std_QuarterlyConsolidatedBalanceSheet',
|
|
77
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_std_SemiAnnualBalanceSheet',
|
|
78
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_std_SemiAnnualConsolidatedBalanceSheet',
|
|
79
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_std_Type1SemiAnnualBalanceSheet',
|
|
80
|
+
'http://disclosure.edinet-fsa.go.jp/role/jppfs/rol_std_Type1SemiAnnualConsolidatedBalanceSheet',
|
|
81
|
+
])
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class StatementType(Enum):
|
|
85
|
+
BALANCE_SHEET = 'BalanceSheet'
|
|
86
|
+
CONSOLIDATED_BALANCE_SHEET = 'ConsolidatedBalanceSheetIFRS'
|
|
87
|
+
STATEMENT_OF_CASH_FLOWS = 'StatementOfCashFlowsIFRS'
|
|
88
|
+
STATEMENT_OF_CHANGES_IN_EQUITY = 'StatementOfChangesInEquityIFRS'
|
|
89
|
+
STATEMENT_OF_COMPREHENSIVE_INCOME = 'StatementOfComprehensiveIncomeIFRS'
|
|
90
|
+
STATEMENT_OF_COMPREHENSIVE_INCOME_SINGLE_STATEMENT = 'StatementOfComprehensiveIncomeSingleStatementIFRS'
|
|
91
|
+
STATEMENT_OF_FINANCIAL_POSITION = 'StatementOfFinancialPositionIFRS'
|
|
92
|
+
STATEMENT_OF_PROFIT_OR_LOSS = 'StatementOfProfitOrLossIFRS'
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@dataclass(frozen=True)
|
|
96
|
+
class Statement:
|
|
97
|
+
isConsolidated: bool
|
|
98
|
+
roleUri: str
|
|
99
|
+
statementType: StatementType
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(frozen=True)
|
|
103
|
+
class BalanceSheet:
|
|
104
|
+
assetsTotal: Decimal
|
|
105
|
+
contextId: str
|
|
106
|
+
facts: list[ModelFact]
|
|
107
|
+
liabilitiesAndEquityTotal: Decimal
|
|
108
|
+
unitId: str
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@dataclass(frozen=True)
|
|
112
|
+
class StatementInstance:
|
|
113
|
+
balanceSheets: list[BalanceSheet]
|
|
114
|
+
statement: Statement
|
|
115
|
+
|
|
116
|
+
def _buildStatements() -> frozenset[Statement]:
|
|
117
|
+
"""
|
|
118
|
+
Build a frozenset of Statement objects from the STATEMENT_ROLE_URIS.
|
|
119
|
+
This is done to avoid re-evaluating the set comprehension multiple times.
|
|
120
|
+
"""
|
|
121
|
+
statements = []
|
|
122
|
+
for roleUri in STATEMENT_ROLE_URIS:
|
|
123
|
+
isConsolidated = bool(CONSOLIDATED_ROLE_URI_PATTERN.match(roleUri))
|
|
124
|
+
statementType=next(
|
|
125
|
+
statementType
|
|
126
|
+
for statementType in StatementType
|
|
127
|
+
if roleUri.endswith(statementType.value)
|
|
128
|
+
)
|
|
129
|
+
statements.append(
|
|
130
|
+
Statement(
|
|
131
|
+
isConsolidated=isConsolidated,
|
|
132
|
+
roleUri=roleUri,
|
|
133
|
+
statementType=statementType
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
return frozenset(statements)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
STATEMENTS = _buildStatements()
|
|
@@ -6,8 +6,6 @@ from __future__ import annotations
|
|
|
6
6
|
from collections import defaultdict
|
|
7
7
|
from typing import Any, Iterable
|
|
8
8
|
|
|
9
|
-
import regex
|
|
10
|
-
|
|
11
9
|
from arelle import XbrlConst
|
|
12
10
|
from arelle.ModelDtsObject import ModelConcept
|
|
13
11
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
@@ -166,14 +164,11 @@ def rule_EC8054W(
|
|
|
166
164
|
for context in val.modelXbrl.contexts.values():
|
|
167
165
|
if pluginData.nonConsolidatedMemberQn.localName not in context.id:
|
|
168
166
|
continue
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
):
|
|
175
|
-
memberQnames.add(memberElt.xValue)
|
|
176
|
-
if pluginData.nonConsolidatedMemberQn not in memberQnames:
|
|
167
|
+
member = context.dimMemberQname(
|
|
168
|
+
pluginData.consolidatedOrNonConsolidatedAxisQn,
|
|
169
|
+
includeDefaults=True
|
|
170
|
+
)
|
|
171
|
+
if member != pluginData.nonConsolidatedMemberQn:
|
|
177
172
|
yield Validation.warning(
|
|
178
173
|
codes='EDINET.EC8054W',
|
|
179
174
|
msg=_("For the context ID (%(contextId)s), \"NonConsolidatedMember\" "
|
|
@@ -3,9 +3,7 @@ See COPYRIGHT.md for copyright information.
|
|
|
3
3
|
"""
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from decimal import Decimal
|
|
8
|
-
from typing import Any, Iterable, cast
|
|
6
|
+
from typing import Any, Iterable
|
|
9
7
|
|
|
10
8
|
from arelle import XbrlConst, ValidateDuplicateFacts
|
|
11
9
|
from arelle.LinkbaseType import LinkbaseType
|
|
@@ -15,12 +13,71 @@ from arelle.typing import TypeGetText
|
|
|
15
13
|
from arelle.utils.PluginHooks import ValidationHook
|
|
16
14
|
from arelle.utils.validate.Decorator import validation
|
|
17
15
|
from arelle.utils.validate.Validation import Validation
|
|
16
|
+
from ..Constants import AccountingStandard
|
|
18
17
|
from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
|
|
19
18
|
from ..PluginValidationDataExtension import PluginValidationDataExtension
|
|
19
|
+
from ..Statement import StatementType
|
|
20
20
|
|
|
21
21
|
_: TypeGetText
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
@validation(
|
|
25
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
26
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
27
|
+
)
|
|
28
|
+
def rule_balances(
|
|
29
|
+
pluginData: PluginValidationDataExtension,
|
|
30
|
+
val: ValidateXbrl,
|
|
31
|
+
*args: Any,
|
|
32
|
+
**kwargs: Any,
|
|
33
|
+
) -> Iterable[Validation]:
|
|
34
|
+
"""
|
|
35
|
+
EDINET.EC8057W: On the consolidated balance sheet, the sum of all liabilities and
|
|
36
|
+
equity must equal the sum of all assets.
|
|
37
|
+
EDINET.EC8058W: On the nonconsolidated balance sheet, the sum of all liabilities and
|
|
38
|
+
equity must equal the sum of all assets.
|
|
39
|
+
EDINET.EC8062W: On the consolidated statement of financial position, the sum of all liabilities and
|
|
40
|
+
equity must equal the sum of all assets.
|
|
41
|
+
EDINET.EC8064W: On the nonconsolidated statement of financial position, the sum of all liabilities and
|
|
42
|
+
equity must equal the sum of all assets.
|
|
43
|
+
"""
|
|
44
|
+
for statementInstance in pluginData.getStatementInstances(val.modelXbrl):
|
|
45
|
+
statement = statementInstance.statement
|
|
46
|
+
for balanceSheet in statementInstance.balanceSheets:
|
|
47
|
+
if balanceSheet.assetsTotal == balanceSheet.liabilitiesAndEquityTotal:
|
|
48
|
+
continue
|
|
49
|
+
code = None
|
|
50
|
+
if statement.statementType == StatementType.BALANCE_SHEET:
|
|
51
|
+
if statement.isConsolidated:
|
|
52
|
+
code = "EDINET.EC8057W"
|
|
53
|
+
else:
|
|
54
|
+
code = "EDINET.EC8058W"
|
|
55
|
+
elif statement.statementType == StatementType.STATEMENT_OF_FINANCIAL_POSITION:
|
|
56
|
+
if statement.isConsolidated:
|
|
57
|
+
code = "EDINET.EC8062W"
|
|
58
|
+
else:
|
|
59
|
+
code = "EDINET.EC8064W"
|
|
60
|
+
assert code is not None, "Unknown balance sheet encountered."
|
|
61
|
+
yield Validation.warning(
|
|
62
|
+
codes=code,
|
|
63
|
+
msg=_("The %(consolidated)s %(balanceSheet)s is not balanced. "
|
|
64
|
+
"The sum of all liabilities and equity must equal the sum of all assets. "
|
|
65
|
+
"Please correct the debit (%(liabilitiesAndEquitySum)s) and credit (%(assetSum)s) "
|
|
66
|
+
"values so that they match "
|
|
67
|
+
"<roleUri=%(roleUri)s> <contextID=%(contextId)s> <unitID=%(unitId)s>."),
|
|
68
|
+
consolidated=_("consolidated") if statement.isConsolidated
|
|
69
|
+
else _("nonconsolidated"),
|
|
70
|
+
balanceSheet=_("balance sheet") if statement.statementType == StatementType.BALANCE_SHEET
|
|
71
|
+
else _("statement of financial position"),
|
|
72
|
+
liabilitiesAndEquitySum=f"{balanceSheet.liabilitiesAndEquityTotal:,}",
|
|
73
|
+
assetSum=f"{balanceSheet.assetsTotal:,}",
|
|
74
|
+
roleUri=statement.roleUri,
|
|
75
|
+
contextId=balanceSheet.contextId,
|
|
76
|
+
unitId=balanceSheet.unitId,
|
|
77
|
+
modelObject=balanceSheet.facts,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
24
81
|
@validation(
|
|
25
82
|
hook=ValidationHook.XBRL_FINALLY,
|
|
26
83
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -90,6 +147,35 @@ def rule_EC5002E(
|
|
|
90
147
|
)
|
|
91
148
|
|
|
92
149
|
|
|
150
|
+
@validation(
|
|
151
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
152
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
153
|
+
)
|
|
154
|
+
def rule_EC5613W(
|
|
155
|
+
pluginData: PluginValidationDataExtension,
|
|
156
|
+
val: ValidateXbrl,
|
|
157
|
+
*args: Any,
|
|
158
|
+
**kwargs: Any,
|
|
159
|
+
) -> Iterable[Validation]:
|
|
160
|
+
"""
|
|
161
|
+
EDINET.EC5613W: Please set the DEI "Accounting Standard" value to one
|
|
162
|
+
of the following: "Japan GAAP", "US GAAP", "IFRS".
|
|
163
|
+
"""
|
|
164
|
+
validAccountingStandards = {s.value for s in AccountingStandard}
|
|
165
|
+
errorFacts = [
|
|
166
|
+
fact for fact in pluginData.iterValidNonNilFacts(val.modelXbrl, pluginData.accountingStandardsDeiQn)
|
|
167
|
+
if fact.xValue not in validAccountingStandards
|
|
168
|
+
]
|
|
169
|
+
if len(errorFacts) > 0:
|
|
170
|
+
yield Validation.warning(
|
|
171
|
+
codes='EDINET.EC5613W',
|
|
172
|
+
msg=_("Please set the DEI \"Accounting Standard\" value to one "
|
|
173
|
+
"of the following: %(values)s."),
|
|
174
|
+
values=', '.join(f'"{s.value}"' for s in AccountingStandard),
|
|
175
|
+
modelObject=errorFacts,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
|
|
93
179
|
@validation(
|
|
94
180
|
hook=ValidationHook.XBRL_FINALLY,
|
|
95
181
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -175,54 +261,6 @@ def rule_EC8027W(
|
|
|
175
261
|
)
|
|
176
262
|
|
|
177
263
|
|
|
178
|
-
@validation(
|
|
179
|
-
hook=ValidationHook.XBRL_FINALLY,
|
|
180
|
-
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
181
|
-
)
|
|
182
|
-
def rule_EC8062W(
|
|
183
|
-
pluginData: PluginValidationDataExtension,
|
|
184
|
-
val: ValidateXbrl,
|
|
185
|
-
*args: Any,
|
|
186
|
-
**kwargs: Any,
|
|
187
|
-
) -> Iterable[Validation]:
|
|
188
|
-
"""
|
|
189
|
-
EDINET.EC8062W: The sum of all liabilities and equity must equal the sum of all assets.
|
|
190
|
-
"""
|
|
191
|
-
deduplicatedFacts = pluginData.getDeduplicatedFacts(val.modelXbrl)
|
|
192
|
-
|
|
193
|
-
factsByContextId = defaultdict(list)
|
|
194
|
-
for fact in deduplicatedFacts:
|
|
195
|
-
if fact.qname not in (pluginData.assetsIfrsQn, pluginData.liabilitiesAndEquityIfrsQn):
|
|
196
|
-
continue
|
|
197
|
-
if fact.contextID is None or not pluginData.contextIdPattern.fullmatch(fact.contextID):
|
|
198
|
-
continue
|
|
199
|
-
factsByContextId[fact.contextID].append(fact)
|
|
200
|
-
|
|
201
|
-
for facts in factsByContextId.values():
|
|
202
|
-
assetSum = Decimal(0)
|
|
203
|
-
liabilitiesAndEquitySum = Decimal(0)
|
|
204
|
-
for fact in facts:
|
|
205
|
-
if isinstance(fact.xValue, float):
|
|
206
|
-
value = Decimal(fact.xValue)
|
|
207
|
-
else:
|
|
208
|
-
value = cast(Decimal, fact.xValue)
|
|
209
|
-
if fact.qname == pluginData.assetsIfrsQn:
|
|
210
|
-
assetSum += value
|
|
211
|
-
elif fact.qname == pluginData.liabilitiesAndEquityIfrsQn:
|
|
212
|
-
liabilitiesAndEquitySum += value
|
|
213
|
-
if assetSum != liabilitiesAndEquitySum:
|
|
214
|
-
yield Validation.warning(
|
|
215
|
-
codes='EDINET.EC8062W',
|
|
216
|
-
msg=_("The consolidated statement of financial position is not reconciled. "
|
|
217
|
-
"The sum of all liabilities and equity must equal the sum of all assets. "
|
|
218
|
-
"Please correct the debit (%(liabilitiesAndEquitySum)s) and credit (%(assetSum)s) "
|
|
219
|
-
"values so that they match."),
|
|
220
|
-
liabilitiesAndEquitySum=f"{liabilitiesAndEquitySum:,}",
|
|
221
|
-
assetSum=f"{assetSum:,}",
|
|
222
|
-
modelObject=facts,
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
|
|
226
264
|
@validation(
|
|
227
265
|
hook=ValidationHook.XBRL_FINALLY,
|
|
228
266
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -3,8 +3,10 @@ See COPYRIGHT.md for copyright information.
|
|
|
3
3
|
"""
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
+
import os
|
|
6
7
|
from collections import defaultdict
|
|
7
8
|
from datetime import timedelta
|
|
9
|
+
from lxml.etree import XML, DTD
|
|
8
10
|
from typing import Any, cast, Iterable
|
|
9
11
|
|
|
10
12
|
import regex
|
|
@@ -28,6 +30,7 @@ from arelle.utils.validate.Validation import Validation
|
|
|
28
30
|
from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
|
|
29
31
|
from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
|
|
30
32
|
from ..PluginValidationDataExtension import PluginValidationDataExtension
|
|
33
|
+
from ..Constants import xhtmlDtdExtension
|
|
31
34
|
|
|
32
35
|
_: TypeGetText
|
|
33
36
|
|
|
@@ -349,6 +352,44 @@ def rule_gfm_1_2_13(
|
|
|
349
352
|
)
|
|
350
353
|
|
|
351
354
|
|
|
355
|
+
@validation(
|
|
356
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
357
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
358
|
+
)
|
|
359
|
+
def rule_gfm_1_2_14(
|
|
360
|
+
pluginData: PluginValidationDataExtension,
|
|
361
|
+
val: ValidateXbrl,
|
|
362
|
+
*args: Any,
|
|
363
|
+
**kwargs: Any,
|
|
364
|
+
) -> Iterable[Validation]:
|
|
365
|
+
"""
|
|
366
|
+
EDINET.EC5700W: [GFM.1.2.14] The content of an element with a data type of nonnum:textBlockItemType is not well-formed XML
|
|
367
|
+
(a format that conforms to XML grammar, such as all start and end tags being paired, and the end tag of a nested tag not coming after the end tag of its parent tag, etc.).
|
|
368
|
+
Please modify it so that it is well-formed.
|
|
369
|
+
"""
|
|
370
|
+
CDATApattern = regex.compile(r"<!\[CDATA\[(.+)\]\]")
|
|
371
|
+
dtd = DTD(os.path.join(val.modelXbrl.modelManager.cntlr.configDir, xhtmlDtdExtension))
|
|
372
|
+
htmlBodyTemplate = "<body><div>\n{0}\n</div></body>\n"
|
|
373
|
+
namedEntityPattern = regex.compile("&[_A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]"
|
|
374
|
+
r"[_\-\.:"
|
|
375
|
+
"\xB7A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u0300-\u036F\u203F-\u2040]*;")
|
|
376
|
+
XMLpattern = regex.compile(r".*(<|<|<|<)[A-Za-z_]+[A-Za-z0-9_:]*[^>]*(/>|>|>|/>).*", regex.DOTALL)
|
|
377
|
+
|
|
378
|
+
for fact in val.modelXbrl.facts:
|
|
379
|
+
concept = fact.concept
|
|
380
|
+
if not fact.isNil and concept is not None and concept.isTextBlock and XMLpattern.match(fact.value):
|
|
381
|
+
for xmlText in [fact.value] + CDATApattern.findall(fact.value):
|
|
382
|
+
xmlBodyWithoutEntities = htmlBodyTemplate.format(namedEntityPattern.sub("", xmlText).replace('&','&'))
|
|
383
|
+
textblockXml = XML(xmlBodyWithoutEntities)
|
|
384
|
+
if not dtd.validate(textblockXml):
|
|
385
|
+
yield Validation.warning(
|
|
386
|
+
codes='EDINET.EC5700W.GFM.1.2.14',
|
|
387
|
+
msg=_('The content of an element with a data type of nonnum:textBlockItemType is not well-formed XML (a format that conforms to XML grammar, '
|
|
388
|
+
'such as all start and end tags being in pairs, and the end tag of a nested tag not coming after the end tag of its parent tag). '
|
|
389
|
+
'Correct the content so that it is well-formed.'),
|
|
390
|
+
modelObject = fact
|
|
391
|
+
)
|
|
392
|
+
|
|
352
393
|
|
|
353
394
|
@validation(
|
|
354
395
|
hook=ValidationHook.XBRL_FINALLY,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: arelle-release
|
|
3
|
-
Version: 2.37.
|
|
3
|
+
Version: 2.37.49
|
|
4
4
|
Summary: An open source XBRL platform.
|
|
5
5
|
Author-email: "arelle.org" <support@arelle.org>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -50,7 +50,9 @@ Requires-Dist: PyMySQL==1.*; extra == "db"
|
|
|
50
50
|
Requires-Dist: pyodbc<6,>=4; extra == "db"
|
|
51
51
|
Requires-Dist: rdflib<8,>=5; extra == "db"
|
|
52
52
|
Provides-Extra: efm
|
|
53
|
+
Requires-Dist: aniso8601==10.*; extra == "efm"
|
|
53
54
|
Requires-Dist: holidays==0.*; extra == "efm"
|
|
55
|
+
Requires-Dist: Matplotlib==3.*; extra == "efm"
|
|
54
56
|
Requires-Dist: pytz; extra == "efm"
|
|
55
57
|
Provides-Extra: esef
|
|
56
58
|
Requires-Dist: tinycss2==1.*; extra == "esef"
|
|
@@ -125,7 +125,7 @@ arelle/XmlValidateConst.py,sha256=U_wN0Q-nWKwf6dKJtcu_83FXPn9c6P8JjzGA5b0w7P0,33
|
|
|
125
125
|
arelle/XmlValidateParticles.py,sha256=Mn6vhFl0ZKC_vag1mBwn1rH_x2jmlusJYqOOuxFPO2k,9231
|
|
126
126
|
arelle/XmlValidateSchema.py,sha256=6frtZOc1Yrx_5yYF6V6oHbScnglWrVbWr6xW4EHtLQI,7428
|
|
127
127
|
arelle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
128
|
-
arelle/_version.py,sha256=
|
|
128
|
+
arelle/_version.py,sha256=Ee0guntzPFkQ3dVGjmJhql2UxZBI6xicDkHrMXRgOlk,515
|
|
129
129
|
arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
|
|
130
130
|
arelle/api/Session.py,sha256=27HVuK3Bz1_21l4_RLn1IQg6v0MNsUEYrHajymyWwxI,7429
|
|
131
131
|
arelle/config/creationSoftwareNames.json,sha256=5MK7XUjfDJ9OpRCCHXeOErJ1SlTBZji4WEcEOdOacx0,3128
|
|
@@ -312,22 +312,23 @@ arelle/plugin/validate/DBA/rules/tm.py,sha256=ui9oKBqlAForwkQ9kk9KBiUogTJE5pv1Rb
|
|
|
312
312
|
arelle/plugin/validate/DBA/rules/tr.py,sha256=4TootFjl0HXsKZk1XNBCyj-vnjRs4lg35hfiz_b_4wU,14684
|
|
313
313
|
arelle/plugin/validate/EBA/__init__.py,sha256=x3zXNcdSDJ3kHfL7kMs0Ve0Vs9oWbzNFVf1TK4Avmy8,45924
|
|
314
314
|
arelle/plugin/validate/EBA/config.xml,sha256=37wMVUAObK-XEqakqD8zPNog20emYt4a_yfL1AKubF8,2022
|
|
315
|
-
arelle/plugin/validate/EDINET/Constants.py,sha256=
|
|
315
|
+
arelle/plugin/validate/EDINET/Constants.py,sha256=QgNO3ZcTfJPMIGogS4Xuyz2BtISJ_PxYP2GmNbshx8c,1136
|
|
316
316
|
arelle/plugin/validate/EDINET/ControllerPluginData.py,sha256=PrEhllue_lh-sLeUy9w8I9XLMLgpo5eW-c7ZKgNyGLE,6256
|
|
317
317
|
arelle/plugin/validate/EDINET/DisclosureSystems.py,sha256=3rKG42Eg-17Xx_KXU_V5yHW6I3LTwQunvf4a44C9k_4,36
|
|
318
318
|
arelle/plugin/validate/EDINET/InstanceType.py,sha256=aLKb4-AJ6nDZKMOLCp7u08E9VD64ExeZy9_oGth-LTk,3207
|
|
319
319
|
arelle/plugin/validate/EDINET/ManifestInstance.py,sha256=SkQV-aOsYn3CTgCkH4IXNdM3QKoiz8okwb29ftMtV3Q,6882
|
|
320
|
-
arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=
|
|
320
|
+
arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=3EhtXN_7q3SBgqiHNzuGwlEe-yT4x1hL1t1jtZG9cYE,10983
|
|
321
|
+
arelle/plugin/validate/EDINET/Statement.py,sha256=0Mw5IB7LMtvUZ-2xKZfxmq67xF_dCgJo3eNLweLFRHU,9350
|
|
321
322
|
arelle/plugin/validate/EDINET/UploadContents.py,sha256=L0u5171cLBKX7NT-_szRqOfkiy4Gv1xPsfpPVgPhtu0,409
|
|
322
323
|
arelle/plugin/validate/EDINET/ValidationPluginExtension.py,sha256=oMY0ntLr1qIh3uMi1W_M-bT5bhXPDx048X3oDFP5zOY,2042
|
|
323
324
|
arelle/plugin/validate/EDINET/__init__.py,sha256=OZ7gMknCHd0M-9nt8UOmjEZW50YQzbvSLongr9O7Yi0,3022
|
|
324
325
|
arelle/plugin/validate/EDINET/resources/config.xml,sha256=7uT4GcRgk5veMLpFhPPQJxbGKiQvM52P8EMrjn0qd0g,646
|
|
325
326
|
arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml,sha256=997I3RGTLg5OY3vn5hQxVFAAxOmDSOYpuyQe6VnWSY0,16285
|
|
326
327
|
arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
327
|
-
arelle/plugin/validate/EDINET/rules/contexts.py,sha256=
|
|
328
|
-
arelle/plugin/validate/EDINET/rules/edinet.py,sha256=
|
|
328
|
+
arelle/plugin/validate/EDINET/rules/contexts.py,sha256=anmkmrrb8kSZRYhrgkh1dlZC1rpCgCtJqZ2TnsBMP5s,7458
|
|
329
|
+
arelle/plugin/validate/EDINET/rules/edinet.py,sha256=pgTmG32uEG8dDPVaBIYE_wN-hKV5AFZL0_wB11L0xHQ,11733
|
|
329
330
|
arelle/plugin/validate/EDINET/rules/frta.py,sha256=N0YglHYZuLD2IuwE26viR2ViwUYjneBuMFU9vlrS0aQ,7616
|
|
330
|
-
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=
|
|
331
|
+
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=udaGzYmKiCudXGE7yA_ej-Tcs3JDaUxHbR87ZITUPLA,24568
|
|
331
332
|
arelle/plugin/validate/EDINET/rules/manifests.py,sha256=MoT9R_a4BzuYdQVbF7RC5wz134Ve68svSdJ3NlpO_AU,4026
|
|
332
333
|
arelle/plugin/validate/EDINET/rules/upload.py,sha256=k1o12K_vMN2N5bAXPxLRwyKjghoOGrgfLijE_j_5ilQ,19811
|
|
333
334
|
arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
|
|
@@ -679,9 +680,9 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
|
|
|
679
680
|
arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
680
681
|
arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
681
682
|
arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
|
|
682
|
-
arelle_release-2.37.
|
|
683
|
-
arelle_release-2.37.
|
|
684
|
-
arelle_release-2.37.
|
|
685
|
-
arelle_release-2.37.
|
|
686
|
-
arelle_release-2.37.
|
|
687
|
-
arelle_release-2.37.
|
|
683
|
+
arelle_release-2.37.49.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
|
|
684
|
+
arelle_release-2.37.49.dist-info/METADATA,sha256=l7IqnpMRntF6T7qKQ6jhMMGggWKen61_a-bAVs7PI6Y,9231
|
|
685
|
+
arelle_release-2.37.49.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
686
|
+
arelle_release-2.37.49.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
|
|
687
|
+
arelle_release-2.37.49.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
|
|
688
|
+
arelle_release-2.37.49.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|