arelle-release 2.37.59__py3-none-any.whl → 2.37.61__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/ModelDtsObject.py CHANGED
@@ -1690,6 +1690,7 @@ class RelationStatus:
1690
1690
  INEFFECTIVE = 4
1691
1691
 
1692
1692
  arcCustAttrsExclusions = {XbrlConst.xlink, "use","priority","order","weight","preferredLabel"}
1693
+ modelObjectAttrs = frozenset(dir(ModelObject))
1693
1694
 
1694
1695
  class ModelRelationship(ModelObject):
1695
1696
  """
@@ -2086,6 +2087,11 @@ class ModelRelationship(ModelObject):
2086
2087
  self.toModelObject.qname if isinstance(self.toModelObject, ModelObject) else "??",
2087
2088
  self.modelDocument.basename, self.sourceline))
2088
2089
 
2090
+ def __dir__(self):
2091
+ # Ignore ModelObject attributes because most relate to the underlying lxml element,
2092
+ # which ModelRelationship does not have.
2093
+ return [a for a in object.__dir__(self) if a.startswith('__') or a not in modelObjectAttrs]
2094
+
2089
2095
  @property
2090
2096
  def viewConcept(self):
2091
2097
  if isinstance(self.toModelObject, ModelConcept):
arelle/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '2.37.59'
32
- __version_tuple__ = version_tuple = (2, 37, 59)
31
+ __version__ = version = '2.37.61'
32
+ __version_tuple__ = version_tuple = (2, 37, 61)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -11,6 +11,8 @@ class AccountingStandard(Enum):
11
11
  US_GAAP = 'US GAAP'
12
12
 
13
13
 
14
+ domainItemTypeQname = qname("{http://www.xbrl.org/dtr/type/non-numeric}nonnum:domainItemType")
15
+
14
16
  qnEdinetManifestInsert = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}insert")
15
17
  qnEdinetManifestInstance = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}instance")
16
18
  qnEdinetManifestItem = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}item")
@@ -42,8 +42,6 @@ from .UploadContents import UploadContents
42
42
  _: TypeGetText
43
43
 
44
44
 
45
- _DEBIT_QNAME_PATTERN = regex.compile('.*(Liability|Liabilities|Equity)')
46
-
47
45
  STANDARD_TAXONOMY_URL_PREFIXES = frozenset((
48
46
  'http://disclosure.edinet-fsa.go.jp/taxonomy/',
49
47
  'https://disclosure.edinet-fsa.go.jp/taxonomy/',
@@ -172,12 +170,6 @@ class PluginValidationDataExtension(PluginData):
172
170
  fileSourcePath = fullPath.relative_to(basePath)
173
171
  controllerPluginData.addUsedFilepath(fileSourcePath)
174
172
 
175
- def _isDebitConcept(self, concept: ModelConcept) -> bool:
176
- """
177
- :return: Whether the given concept is a debit concept.
178
- """
179
- return bool(_DEBIT_QNAME_PATTERN.match(concept.qname.localName))
180
-
181
173
  @lru_cache(1)
182
174
  def isCorporateForm(self, modelXbrl: ModelXbrl) -> bool:
183
175
  formTypes = self.getFormTypes(modelXbrl)
@@ -247,23 +239,23 @@ class PluginValidationDataExtension(PluginData):
247
239
  for (contextId, unitId), facts in factsByContextIdAndUnitId.items():
248
240
  if not self._contextMatchesStatement(modelXbrl, contextId, statement):
249
241
  continue
250
- assetSum = Decimal(0)
251
- liabilitiesAndEquitySum = Decimal(0)
242
+ creditSum = Decimal(0)
243
+ debitSum = Decimal(0)
252
244
  for fact in facts:
253
245
  if isinstance(fact.xValue, float):
254
246
  value = Decimal(fact.xValue)
255
247
  else:
256
248
  value = cast(Decimal, fact.xValue)
257
- if self._isDebitConcept(fact.concept):
258
- liabilitiesAndEquitySum += value
259
- else:
260
- assetSum += value
249
+ if fact.concept.balance == "debit":
250
+ debitSum += value
251
+ elif fact.concept.balance == "credit":
252
+ creditSum += value
261
253
  balanceSheets.append(
262
254
  BalanceSheet(
263
- assetsTotal=assetSum,
255
+ creditSum=creditSum,
264
256
  contextId=str(contextId),
265
257
  facts=facts,
266
- liabilitiesAndEquityTotal=liabilitiesAndEquitySum,
258
+ debitSum=debitSum,
267
259
  unitId=str(unitId),
268
260
  )
269
261
  )
@@ -481,6 +473,17 @@ class PluginValidationDataExtension(PluginData):
481
473
  def isStandardTaxonomyUrl(self, uri: str, modelXbrl: ModelXbrl) -> bool:
482
474
  return modelXbrl.modelManager.disclosureSystem.hrefValidForDisclosureSystem(uri)
483
475
 
476
+ def iterCoverPages(self, modelXbrl: ModelXbrl) -> Iterable[ModelDocument]:
477
+ uploadContents = self.getUploadContents(modelXbrl)
478
+ if uploadContents is None:
479
+ return
480
+ for url, doc in modelXbrl.urlDocs.items():
481
+ path = Path(url)
482
+ pathInfo = uploadContents.uploadPathsByFullPath.get(path)
483
+ if pathInfo is None or not pathInfo.isCoverPage:
484
+ continue
485
+ yield doc
486
+
484
487
  def iterFacts(self, modelXbrl: ModelXbrl, qname: QName) -> Iterable[ModelFact]:
485
488
  yield from modelXbrl.factsByQname.get(qname, set())
486
489
 
@@ -101,10 +101,10 @@ class Statement:
101
101
 
102
102
  @dataclass(frozen=True)
103
103
  class BalanceSheet:
104
- assetsTotal: Decimal
104
+ creditSum: Decimal
105
105
  contextId: str
106
106
  facts: list[ModelFact]
107
- liabilitiesAndEquityTotal: Decimal
107
+ debitSum: Decimal
108
108
  unitId: str
109
109
 
110
110
 
@@ -44,7 +44,7 @@ def rule_balances(
44
44
  for statementInstance in pluginData.getStatementInstances(val.modelXbrl):
45
45
  statement = statementInstance.statement
46
46
  for balanceSheet in statementInstance.balanceSheets:
47
- if balanceSheet.assetsTotal == balanceSheet.liabilitiesAndEquityTotal:
47
+ if balanceSheet.creditSum == balanceSheet.debitSum:
48
48
  continue
49
49
  code = None
50
50
  if statement.statementType == StatementType.BALANCE_SHEET:
@@ -62,15 +62,15 @@ def rule_balances(
62
62
  codes=code,
63
63
  msg=_("The %(consolidated)s %(balanceSheet)s is not balanced. "
64
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) "
65
+ "Please correct the debit (%(debitSum)s) and credit (%(creditSum)s) "
66
66
  "values so that they match "
67
67
  "<roleUri=%(roleUri)s> <contextID=%(contextId)s> <unitID=%(unitId)s>."),
68
68
  consolidated=_("consolidated") if statement.isConsolidated
69
69
  else _("nonconsolidated"),
70
70
  balanceSheet=_("balance sheet") if statement.statementType == StatementType.BALANCE_SHEET
71
71
  else _("statement of financial position"),
72
- liabilitiesAndEquitySum=f"{balanceSheet.liabilitiesAndEquityTotal:,}",
73
- assetSum=f"{balanceSheet.assetsTotal:,}",
72
+ debitSum=f"{balanceSheet.debitSum:,}",
73
+ creditSum=f"{balanceSheet.creditSum:,}",
74
74
  roleUri=statement.roleUri,
75
75
  contextId=balanceSheet.contextId,
76
76
  unitId=balanceSheet.unitId,
@@ -93,14 +93,27 @@ def rule_EC1057E(
93
93
  Ensure that there is a nonnil value disclosed for FilingDateCoverPage
94
94
  Note: This rule is only applicable to the public documents.
95
95
  """
96
- dei = pluginData.getFormTypes(val.modelXbrl)
97
- if len(dei) > 0:
96
+ facts = [
97
+ fact
98
+ for qname in (
99
+ pluginData.jpcrpEsrFilingDateCoverPageQn,
100
+ pluginData.jpcrpFilingDateCoverPageQn,
101
+ pluginData.jpspsFilingDateCoverPageQn
102
+ )
103
+ for fact in pluginData.iterValidNonNilFacts(val.modelXbrl, qname)
104
+ ]
105
+ for modelDocument in pluginData.iterCoverPages(val.modelXbrl):
106
+ if any(fact.modelDocument == modelDocument for fact in facts):
107
+ continue
98
108
  if not (pluginData.hasValidNonNilFact(val.modelXbrl, pluginData.jpcrpEsrFilingDateCoverPageQn)
99
109
  or pluginData.hasValidNonNilFact(val.modelXbrl, pluginData.jpcrpFilingDateCoverPageQn)
100
110
  or pluginData.hasValidNonNilFact(val.modelXbrl, pluginData.jpspsFilingDateCoverPageQn)):
101
111
  yield Validation.error(
102
112
  codes='EDINET.EC1057E',
103
- msg=_("The [Submission Date] on the cover page has not been filled in."),
113
+ msg=_("There is no submission date ('【提出日】') on the cover page. "
114
+ "File name: '%(file)s'. "
115
+ "Please add '【提出日】' to the relevant file."),
116
+ file=modelDocument.basename,
104
117
  )
105
118
 
106
119
 
@@ -12,7 +12,7 @@ import regex
12
12
  from arelle import XbrlConst, XmlUtil
13
13
  from arelle.LinkbaseType import LinkbaseType
14
14
  from arelle.ModelDtsObject import ModelConcept
15
- from arelle.ModelInstanceObject import ModelFact
15
+ from arelle.ModelInstanceObject import ModelFact, ModelInlineFootnote
16
16
  from arelle.ModelObject import ModelObject
17
17
  from arelle.ModelValue import QName
18
18
  from arelle.PrototypeDtsObject import LocPrototype, ArcPrototype
@@ -28,7 +28,7 @@ from arelle.utils.Units import getDuplicateUnitGroups
28
28
  from arelle.utils.validate.Decorator import validation
29
29
  from arelle.utils.validate.Validation import Validation
30
30
  from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
31
- from ..Constants import NUMERIC_LABEL_ROLES
31
+ from ..Constants import NUMERIC_LABEL_ROLES, domainItemTypeQname
32
32
  from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
33
33
  from ..PluginValidationDataExtension import PluginValidationDataExtension
34
34
 
@@ -676,6 +676,35 @@ def rule_gfm_1_3_8(
676
676
  )
677
677
 
678
678
 
679
+ @validation(
680
+ hook=ValidationHook.XBRL_FINALLY,
681
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
682
+ )
683
+ def rule_gfm_1_3_19(
684
+ pluginData: PluginValidationDataExtension,
685
+ val: ValidateXbrl,
686
+ *args: Any,
687
+ **kwargs: Any,
688
+ ) -> Iterable[Validation]:
689
+ """
690
+ EDINET.EC5700W: [GFM 1.3.19] The id attribute of the element defined in the submitter-specific taxonomy
691
+ should be set in the following format:{namespace prefix}_{element name}.
692
+ """
693
+ improperlyFormattedIds = set()
694
+ for concept in pluginData.getExtensionConcepts(val.modelXbrl):
695
+ prefix = concept.qname.prefix or ""
696
+ name = concept.qname.localName
697
+ requiredId = f"{prefix}_{name}"
698
+ if concept.id != requiredId or not prefix:
699
+ improperlyFormattedIds.add(concept)
700
+ if len(improperlyFormattedIds) > 0:
701
+ yield Validation.warning(
702
+ codes='EDINET.EC5700W.GFM.1.3.19',
703
+ msg=_("The id attribute of the element defined in the submitter-specific taxonomy should be set in the following format: {namespace prefix}_{element name}"),
704
+ modelObject=improperlyFormattedIds
705
+ )
706
+
707
+
679
708
  @validation(
680
709
  hook=ValidationHook.XBRL_FINALLY,
681
710
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -783,6 +812,115 @@ def rule_gfm_1_3_23(
783
812
  )
784
813
 
785
814
 
815
+ @validation(
816
+ hook=ValidationHook.XBRL_FINALLY,
817
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
818
+ )
819
+ def rule_gfm_1_3_25(
820
+ pluginData: PluginValidationDataExtension,
821
+ val: ValidateXbrl,
822
+ *args: Any,
823
+ **kwargs: Any,
824
+ ) -> Iterable[Validation]:
825
+ """
826
+ EDINET.EC5700W: [GFM 1.3.25] Correct the element name so that it does not end with "Axis", or correct the
827
+ substitutionGroup to "xbrldt:dimensionItem".
828
+
829
+ GFM 1.3.25: The xsd:element substitutionGroup attribute must equal "xbrldt:dimensionItem" if
830
+ and only if the name attribute ends with "Axis".
831
+ """
832
+ for concept in pluginData.getExtensionConcepts(val.modelXbrl):
833
+ if concept.qname.localName.endswith("Axis") != (concept.substitutionGroupQname == XbrlConst.qnXbrldtDimensionItem):
834
+ yield Validation.warning(
835
+ codes='EDINET.EC5700W.GFM.1.3.25',
836
+ msg=_("Modify the element name, '%(conceptName)s', so that it does not end with 'Axis', or modify the substitutionGroup to 'xbrldt:dimensionItem'."),
837
+ conceptName=concept.qname.localName,
838
+ modelObject=concept,
839
+ )
840
+
841
+
842
+ @validation(
843
+ hook=ValidationHook.XBRL_FINALLY,
844
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
845
+ )
846
+ def rule_gfm_1_3_26(
847
+ pluginData: PluginValidationDataExtension,
848
+ val: ValidateXbrl,
849
+ *args: Any,
850
+ **kwargs: Any,
851
+ ) -> Iterable[Validation]:
852
+ """
853
+ EDINET.EC5700W: [GFM 1.3.26] Correct the element name so that it does not end with "Table", or correct the
854
+ substitutionGroup to "xbrldt:hypercubeItem".
855
+
856
+ GFM 1.3.26: The xsd:element name attribute must ends with "Table" if and only if
857
+ substitutionGroup attribute equals "xbrldt:hypercubeItem".
858
+ """
859
+ for concept in pluginData.getExtensionConcepts(val.modelXbrl):
860
+ if concept.qname.localName.endswith("Table") != (concept.substitutionGroupQname == XbrlConst.qnXbrldtHypercubeItem):
861
+ yield Validation.warning(
862
+ codes='EDINET.EC5700W.GFM.1.3.26',
863
+ msg=_("The substitution group 'xbrldt:hypercubeItem' is only allowed with an element name that ends with 'Table'."
864
+ "Please change %(conceptName)s or change the substitutionGroup."),
865
+ conceptName=concept.qname.localName,
866
+ modelObject=concept
867
+ )
868
+
869
+
870
+ @validation(
871
+ hook=ValidationHook.XBRL_FINALLY,
872
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
873
+ )
874
+ def rule_gfm_1_3_28(
875
+ pluginData: PluginValidationDataExtension,
876
+ val: ValidateXbrl,
877
+ *args: Any,
878
+ **kwargs: Any,
879
+ ) -> Iterable[Validation]:
880
+ """
881
+ EDINET.EC5700W: [GFM 1.3.28] If the element name of an element extended by a submitter-specific taxonomy ends with "LineItems",
882
+ set the abstract attribute to "true".
883
+ """
884
+ for concept in pluginData.getExtensionConcepts(val.modelXbrl):
885
+ if concept.qname.localName.endswith("LineItems") and not concept.isAbstract:
886
+ yield Validation.warning(
887
+ codes='EDINET.EC5700W.GFM.1.3.28',
888
+ msg=_("If the element name of an element extended by a submitter-specific taxonomy ends with 'LineItems', "
889
+ "set the abstract attribute to 'true'. For the element, '%(conceptName)s', the abstract attribute is 'false'."),
890
+ conceptName=concept.qname.localName,
891
+ modelObject=concept
892
+ )
893
+
894
+
895
+ @validation(
896
+ hook=ValidationHook.XBRL_FINALLY,
897
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
898
+ )
899
+ def rule_gfm_1_3_29(
900
+ pluginData: PluginValidationDataExtension,
901
+ val: ValidateXbrl,
902
+ *args: Any,
903
+ **kwargs: Any,
904
+ ) -> Iterable[Validation]:
905
+ """
906
+ EDINET.EC5700W: [GFM 1.3.29] If the element name of an element extended by the submitter-specific taxonomy ends with
907
+ "Domain" or "Member", please set the type attribute to "nonnum:domainItemType".
908
+
909
+ GFM 1.3.29: The xsd:element name attribute must end with "Domain" or "Member" if and only
910
+ if the type attribute equals "nonnum:domainItemType".
911
+ """
912
+ for concept in pluginData.getExtensionConcepts(val.modelXbrl):
913
+ isConceptDomain = concept.type.isDomainItemType if concept.type is not None else False
914
+ if ((concept.qname.localName.endswith("Domain") or concept.qname.localName.endswith("Member")) != isConceptDomain):
915
+ yield Validation.warning(
916
+ codes='EDINET.EC5700W.GFM.1.3.29',
917
+ msg=_("The type 'us-types:domainItemType' is only allowed with an element name that ends with 'Domain' or 'Member'. "
918
+ "Please change %(conceptName)s or change the type."),
919
+ conceptName=concept.qname.localName,
920
+ modelObject=concept
921
+ )
922
+
923
+
786
924
  @validation(
787
925
  hook=ValidationHook.XBRL_FINALLY,
788
926
  disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
@@ -858,10 +996,13 @@ def rule_gfm_1_5_6(
858
996
  labelRels = labelRelationshipSet.fromModelObject(concept)
859
997
  for rel in labelRels:
860
998
  label = rel.toModelObject
861
- if label.role != XbrlConst.documentationLabel and label.viewText() is not None and len(label.viewText()) >= 511:
999
+ if (label is not None and
1000
+ label.role != XbrlConst.documentationLabel and
1001
+ label.viewText() is not None and
1002
+ len(label.viewText()) >= 511):
862
1003
  yield Validation.warning(
863
1004
  codes='EDINET.EC5700W.GFM.1.5.6',
864
- msg=_("The concept of '%(concept)s' has a label classified as '%(role)s' that is longer than 511 characters: %(label)s"),
1005
+ msg=_("The concept of '%(concept)s' has a label classified as '%(role)s' that is greater than or equal to 511 characters: %(label)s"),
865
1006
  concept=concept.qname,
866
1007
  role=label.role,
867
1008
  label=label.viewText(),
@@ -890,7 +1031,7 @@ def rule_gfm_1_5_7(
890
1031
  labelRels = labelRelationshipSet.fromModelObject(concept)
891
1032
  for rel in labelRels:
892
1033
  label = rel.toModelObject
893
- if label.role != XbrlConst.documentationLabel and label.textValue is not None:
1034
+ if label is not None and label.role != XbrlConst.documentationLabel and label.textValue is not None:
894
1035
  if '<' in label.textValue:
895
1036
  yield Validation.warning(
896
1037
  codes='EDINET.EC5700W.GFM.1.5.7',
@@ -931,7 +1072,7 @@ def rule_gfm_1_5_8(
931
1072
  labelRels = labelRelationshipSet.fromModelObject(concept)
932
1073
  for rel in labelRels:
933
1074
  label = rel.toModelObject
934
- if label.textValue is not None and label.textValue != label.textValue.strip():
1075
+ if label is not None and label.textValue is not None and label.textValue != label.textValue.strip():
935
1076
  yield Validation.warning(
936
1077
  codes='EDINET.EC5700W.GFM.1.5.8',
937
1078
  msg=_("The concept of '%(concept)s' has a label that contains disallowed white space either at the begining or the end: '%(label)s'"),
@@ -963,7 +1104,9 @@ def rule_gfm_1_5_10(
963
1104
  labelRels = labelRelationshipSet.fromModelObject(concept)
964
1105
  for rel in labelRels:
965
1106
  label = rel.toModelObject
966
- if not pluginData.isStandardTaxonomyUrl(label.modelDocument.uri, val.modelXbrl) and label.role in NUMERIC_LABEL_ROLES:
1107
+ if (label is not None and
1108
+ not pluginData.isStandardTaxonomyUrl(label.modelDocument.uri, val.modelXbrl) and
1109
+ label.role in NUMERIC_LABEL_ROLES):
967
1110
  yield Validation.warning(
968
1111
  codes='EDINET.EC5700W.GFM.1.5.10',
969
1112
  msg=_("The non-numeric concept of '%(concept)s' has a label with a numeric role of '%(labelrole)s'"),
@@ -1207,3 +1350,154 @@ def rule_gfm_1_8_1(
1207
1350
  msg=_("The definition relationship is missing the order attribute"),
1208
1351
  modelObject=rel
1209
1352
  )
1353
+
1354
+
1355
+ @validation(
1356
+ hook=ValidationHook.XBRL_FINALLY,
1357
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1358
+ )
1359
+ def rule_gfm_1_8_3(
1360
+ pluginData: PluginValidationDataExtension,
1361
+ val: ValidateXbrl,
1362
+ *args: Any,
1363
+ **kwargs: Any,
1364
+ ) -> Iterable[Validation]:
1365
+ """
1366
+ EDINET.EC5700W: [GFM 1.8.3] The target of an effective arc with an xlink:arcrole attribute equal to
1367
+ "http://xbrl.org/int/dim/arcrole/dimension-domain" or
1368
+ "http://xbrl.org/int/arcrole/dimension-default" must be of type
1369
+ nonnum:domainItemType.
1370
+ """
1371
+ dimensionRelationshipSet = val.modelXbrl.relationshipSet((XbrlConst.dimensionDomain, XbrlConst.dimensionDefault))
1372
+ if dimensionRelationshipSet is None:
1373
+ return
1374
+ for rel in dimensionRelationshipSet.modelRelationships:
1375
+ toConcept = rel.toModelObject
1376
+ if toConcept is not None and toConcept.typeQname != domainItemTypeQname:
1377
+ yield Validation.warning(
1378
+ codes='EDINET.EC5700W.GFM.1.8.3',
1379
+ msg=_("The definition relationship target concept of '%(concept)s' has a type of '%(type)s' instead of 'nonnum:domainItemType'."),
1380
+ concept=toConcept.qname,
1381
+ type=toConcept.typeQname,
1382
+ modelObject=rel
1383
+ )
1384
+
1385
+
1386
+ @validation(
1387
+ hook=ValidationHook.XBRL_FINALLY,
1388
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1389
+ )
1390
+ def rule_gfm_1_8_10(
1391
+ pluginData: PluginValidationDataExtension,
1392
+ val: ValidateXbrl,
1393
+ *args: Any,
1394
+ **kwargs: Any,
1395
+ ) -> Iterable[Validation]:
1396
+ """
1397
+ EDINET.EC5700W: [GFM 1.8.10] Definition relationships must have unique order attributes
1398
+ """
1399
+ definitionRelationshipSet = val.modelXbrl.relationshipSet(tuple(LinkbaseType.DEFINITION.getArcroles()))
1400
+ if definitionRelationshipSet is None:
1401
+ return
1402
+ for modelObject, rels in definitionRelationshipSet.loadModelRelationshipsFrom().items():
1403
+ if len(rels) <= 1:
1404
+ continue
1405
+ relsByOrder = defaultdict(list)
1406
+ for rel in rels:
1407
+ order = rel.arcElement.get("order")
1408
+ if order is not None:
1409
+ relsByOrder[(order, rel.linkrole, rel.arcrole)].append(rel)
1410
+ for key, orderRels in relsByOrder.items():
1411
+ if len(orderRels) > 1:
1412
+ yield Validation.warning(
1413
+ codes='EDINET.EC5700W.GFM.1.8.10',
1414
+ msg=_("The definition relationships have the same order attribute: '%(order)s'"),
1415
+ order=key[0],
1416
+ modelObject=orderRels
1417
+ )
1418
+
1419
+
1420
+ @validation(
1421
+ hook=ValidationHook.XBRL_FINALLY,
1422
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1423
+ )
1424
+ def rule_gfm_1_8_11(
1425
+ pluginData: PluginValidationDataExtension,
1426
+ val: ValidateXbrl,
1427
+ *args: Any,
1428
+ **kwargs: Any,
1429
+ ) -> Iterable[Validation]:
1430
+ """
1431
+ EDINET.EC5700W: [GFM 1.8.11] Definition relationships can not have the xbrldt:usable attribute set to False
1432
+ """
1433
+ definitionRelationshipSet = val.modelXbrl.relationshipSet(tuple(LinkbaseType.DEFINITION.getArcroles()))
1434
+ if definitionRelationshipSet is None:
1435
+ return
1436
+ for rel in definitionRelationshipSet.modelRelationships:
1437
+ if rel.arcrole in [XbrlConst.dimensionDomain, XbrlConst.domainMember]:
1438
+ continue
1439
+ if not rel.isUsable:
1440
+ yield Validation.warning(
1441
+ codes='EDINET.EC5700W.GFM.1.8.11',
1442
+ msg=_("The definition relationship can not have the xbrldt:usable attribute set to False"),
1443
+ modelObject=rel
1444
+ )
1445
+
1446
+
1447
+ @validation(
1448
+ hook=ValidationHook.XBRL_FINALLY,
1449
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1450
+ )
1451
+ def rule_gfm_1_9_1(
1452
+ pluginData: PluginValidationDataExtension,
1453
+ val: ValidateXbrl,
1454
+ *args: Any,
1455
+ **kwargs: Any,
1456
+ ) -> Iterable[Validation]:
1457
+ """
1458
+ EDINET.EC5700W: [GFM 1.9.1] References should not be defined for extension concepts.
1459
+ """
1460
+ conceptReferenceSet = val.modelXbrl.relationshipSet(XbrlConst.conceptReference)
1461
+ for modelConcept in conceptReferenceSet.fromModelObjects():
1462
+ if not isinstance(modelConcept, ModelConcept):
1463
+ continue
1464
+ if modelConcept.qname is None or modelConcept.qname.namespaceURI is None:
1465
+ continue
1466
+ if pluginData.isExtensionUri(modelConcept.qname.namespaceURI, val.modelXbrl):
1467
+ yield Validation.warning(
1468
+ codes='EDINET.EC5700W.GFM.1.9.1',
1469
+ msg=_("References should not be defined for extension concepts: %(conceptName)s"),
1470
+ conceptName=modelConcept.qname,
1471
+ modelObject=modelConcept
1472
+ )
1473
+
1474
+
1475
+ @validation(
1476
+ hook=ValidationHook.XBRL_FINALLY,
1477
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
1478
+ )
1479
+ def rule_gfm_1_10_14(
1480
+ pluginData: PluginValidationDataExtension,
1481
+ val: ValidateXbrl,
1482
+ *args: Any,
1483
+ **kwargs: Any,
1484
+ ) -> Iterable[Validation]:
1485
+ """
1486
+ EDINET.EC5700W: [GFM 1.10.14] All non-empty footnotes must be referenced by an element
1487
+ """
1488
+ footnotes = set()
1489
+ usedFootnoteIDs = set()
1490
+ for ixdsHtmlRootElt in val.modelXbrl.ixdsHtmlElements:
1491
+ for elt in ixdsHtmlRootElt.iterdescendants(XbrlConst.qnIXbrlFootnote.clarkNotation, XbrlConst.qnIXbrl11Footnote.clarkNotation):
1492
+ if isinstance(elt, ModelInlineFootnote) and elt.value != '':
1493
+ footnotes.add(elt)
1494
+ for rel in val.modelXbrl.relationshipSet("XBRL-footnotes").modelRelationships:
1495
+ if rel.fromModelObject is not None and rel.toModelObject is not None:
1496
+ usedFootnoteIDs.add(rel.toModelObject.footnoteID)
1497
+ for footnote in footnotes:
1498
+ if footnote.footnoteID not in usedFootnoteIDs:
1499
+ yield Validation.warning(
1500
+ codes='EDINET.EC5700W.GFM.1.10.14',
1501
+ msg=_("A non-empty footnote is not referenced by an element"),
1502
+ modelObject=footnote
1503
+ )
@@ -271,19 +271,37 @@ def rule_EC0132E(
271
271
  **kwargs: Any,
272
272
  ) -> Iterable[Validation]:
273
273
  """
274
- EDINET.EC0132E: Store the manifest file directly under the relevant folder.
274
+ EDINET.EC0132E: Cover page or manifest file is missing.
275
+
276
+ Note: Cover page is not required in AuditDoc.
275
277
  """
276
278
  uploadContents = pluginData.getUploadContents()
277
279
  if uploadContents is None:
278
280
  return
279
281
  for reportFolderType, paths in uploadContents.reports.items():
280
282
  if reportFolderType.isAttachment:
283
+ # These rules don't apply to "Attach" directories
281
284
  continue
282
- if reportFolderType.manifestPath not in paths:
285
+ coverPageFound = False
286
+ manifestFound = False
287
+ for path in paths:
288
+ pathInfo = uploadContents.uploadPathsByPath[path]
289
+ if pathInfo.isCoverPage:
290
+ coverPageFound = True
291
+ if path == reportFolderType.manifestPath:
292
+ manifestFound = True
293
+ if not coverPageFound and reportFolderType != ReportFolderType.AUDIT_DOC:
294
+ yield Validation.error(
295
+ codes='EDINET.EC0132E',
296
+ msg=_("Cover page does not exist in '%(expectedManifestDirectory)s'. "
297
+ "Please store the cover file directly under the relevant folder and upload it again. "),
298
+ expectedManifestDirectory=str(reportFolderType.manifestPath.parent),
299
+ )
300
+ if not manifestFound:
283
301
  yield Validation.error(
284
302
  codes='EDINET.EC0132E',
285
303
  msg=_("'%(expectedManifestName)s' does not exist in '%(expectedManifestDirectory)s'. "
286
- "Please store the manifest file (or cover file) directly under the relevant folder and upload it again. "),
304
+ "Please store the manifest file directly under the relevant folder and upload it again. "),
287
305
  expectedManifestName=reportFolderType.manifestPath.name,
288
306
  expectedManifestDirectory=str(reportFolderType.manifestPath.parent),
289
307
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arelle-release
3
- Version: 2.37.59
3
+ Version: 2.37.61
4
4
  Summary: An open source XBRL platform.
5
5
  Author-email: "arelle.org" <support@arelle.org>
6
6
  License-Expression: Apache-2.0
@@ -59,7 +59,7 @@ Requires-Dist: tinycss2<2,>=1; extra == "esef"
59
59
  Provides-Extra: objectmaker
60
60
  Requires-Dist: graphviz<1,>=0; extra == "objectmaker"
61
61
  Provides-Extra: webserver
62
- Requires-Dist: cheroot<11,>=8; extra == "webserver"
62
+ Requires-Dist: cheroot<12,>=8; extra == "webserver"
63
63
  Requires-Dist: tornado<7,>=6; extra == "webserver"
64
64
  Provides-Extra: xule
65
65
  Requires-Dist: aniso8601<11,>=10; extra == "xule"
@@ -37,7 +37,7 @@ arelle/LinkbaseType.py,sha256=BwRQl4XZFFCopufC2FEMLhYENNTk2JUWVQvnIUsaqtI,3108
37
37
  arelle/LocalViewer.py,sha256=WVrfek_bLeFFxgWITi1EQb6xCQN8O9Ks-ZL16vRncSk,3080
38
38
  arelle/Locale.py,sha256=07IDxv8nIfvhyRRllFdEAKRI3yo1D2v781cTrjb_RoQ,33193
39
39
  arelle/ModelDocument.py,sha256=R4uVfqks2XRDziRPAp_AUFebrAQBf4FgG97nb5h7fAs,130651
40
- arelle/ModelDtsObject.py,sha256=nvHQs4BDmPxY6mqLiBuqIGRJXyA1EqOEGB2f3S6A6w4,88656
40
+ arelle/ModelDtsObject.py,sha256=VUDsq8Ua0a-Hrhu-vFMaajwZLKjjr7xC4e-LAJSz-k0,88968
41
41
  arelle/ModelFormulaObject.py,sha256=-eb0lBYciEeAvvGduIs3AHGNGrxge9_0g1cVT6UUgvc,122560
42
42
  arelle/ModelInstanceObject.py,sha256=77rkxl1FK8OyJhTXkrNv6B_4oEK6IZm9eRQdFDxslGk,74278
43
43
  arelle/ModelManager.py,sha256=QUNcD2LC_YyyGFU8bFTSuzIGI1qpOK55KBlQ697Ep1I,11075
@@ -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=OtIOO8dIBzaWUcN4ZpZMg03PbgyJW5ESDOu8koDT508,708
128
+ arelle/_version.py,sha256=KHvyigprh_4GfUyMHpRp8DoND89ZqncU0BKzMo7CvWY,708
129
129
  arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
130
130
  arelle/api/Session.py,sha256=kgSxS7VckA1sQ7xp0pJiK7IK-vRxAdAZKUo8gEx27s8,7549
131
131
  arelle/config/creationSoftwareNames.json,sha256=5MK7XUjfDJ9OpRCCHXeOErJ1SlTBZji4WEcEOdOacx0,3128
@@ -312,16 +312,16 @@ 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=6LVzBTt4045SxUjeQa37tlN8zYLF1QIz16khYo3eY4A,2418
315
+ arelle/plugin/validate/EDINET/Constants.py,sha256=I8d-oc9wG-mImV-3Cv3tInP3QjfWO7DeltbuOepyF58,2514
316
316
  arelle/plugin/validate/EDINET/ControllerPluginData.py,sha256=1WhiS0RdrxeXz4pGDzWATEPqCopOh2spr8Z6Qra_Psk,8420
317
317
  arelle/plugin/validate/EDINET/CoverPageRequirements.py,sha256=ZR8pk1CQfUIi15as1zVF27W0kRlUF1M_Ygw7appDUno,4488
318
318
  arelle/plugin/validate/EDINET/DisclosureSystems.py,sha256=3rKG42Eg-17Xx_KXU_V5yHW6I3LTwQunvf4a44C9k_4,36
319
319
  arelle/plugin/validate/EDINET/FilingFormat.py,sha256=SFZ22zFk6RVIA9dpx3iVLlf2heKfZZqt2ZUXUje4BII,18789
320
320
  arelle/plugin/validate/EDINET/FormType.py,sha256=jFqjJACJJ4HhkY1t6Fqei0z6rgvH3Mp-dP04KwQVv3Q,2517
321
321
  arelle/plugin/validate/EDINET/ManifestInstance.py,sha256=o6BGlaQHSsn6D0VKH4zn59UscKnjTKlo99kSGfGdYlU,6910
322
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=9YXy4f1EIYq4NGWaOP7dXjVStdtH4Mb4D4wACrIa2PU,22540
322
+ arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=iA72MJv4r5hhLY5w9YBqQ279RI6ndivXGW-PqqK5rJM,22663
323
323
  arelle/plugin/validate/EDINET/ReportFolderType.py,sha256=Q-9a-5tJfhK-cjY8WUB2AT1NI-Nn9cFtARVOIJoLRGU,2979
324
- arelle/plugin/validate/EDINET/Statement.py,sha256=0Mw5IB7LMtvUZ-2xKZfxmq67xF_dCgJo3eNLweLFRHU,9350
324
+ arelle/plugin/validate/EDINET/Statement.py,sha256=CGq8c647pIEBQtOv8AL0U4knT8HofOdK8IaUjHrcOYU,9331
325
325
  arelle/plugin/validate/EDINET/UploadContents.py,sha256=o29mDoX48M3S2jQqrJO4ZaulltAPt4vD-qdsWTMCUPc,1196
326
326
  arelle/plugin/validate/EDINET/ValidationPluginExtension.py,sha256=8LNqvXzNaWP54dShEjet5ely4BnM8ByCSyimKpUx3_s,2577
327
327
  arelle/plugin/validate/EDINET/__init__.py,sha256=T_p2phcMw1lR4J1X4gvqJPEcZNJdJXtaPpc159A-3_8,3298
@@ -330,11 +330,11 @@ arelle/plugin/validate/EDINET/resources/cover-page-requirements.csv,sha256=8ILKN
330
330
  arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml,sha256=997I3RGTLg5OY3vn5hQxVFAAxOmDSOYpuyQe6VnWSY0,16285
331
331
  arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
332
332
  arelle/plugin/validate/EDINET/rules/contexts.py,sha256=KPoyWfRaURvxoGVcWP64mTMTAKPMSmQSX06RClCLddw,7590
333
- arelle/plugin/validate/EDINET/rules/edinet.py,sha256=g3IPMV5-mWbVwVmEwv5-h1LOtdfeBQ9gZI27m744FFw,12628
333
+ arelle/plugin/validate/EDINET/rules/edinet.py,sha256=1dHYl0nqZ5ql0SaE9Jj95fGegOMlssQNayeebV0iCJQ,13118
334
334
  arelle/plugin/validate/EDINET/rules/frta.py,sha256=N0YglHYZuLD2IuwE26viR2ViwUYjneBuMFU9vlrS0aQ,7616
335
- arelle/plugin/validate/EDINET/rules/gfm.py,sha256=BAcH_yVnJw3abMfsUBk_skZAjB96h-lff795OdnozvQ,45905
335
+ arelle/plugin/validate/EDINET/rules/gfm.py,sha256=XcWjLUxQs521Jbdr3S96RDlJld2m2d3xFFsaRTrP-qM,58037
336
336
  arelle/plugin/validate/EDINET/rules/manifests.py,sha256=MoT9R_a4BzuYdQVbF7RC5wz134Ve68svSdJ3NlpO_AU,4026
337
- arelle/plugin/validate/EDINET/rules/upload.py,sha256=E_sEhsuUkoH648PGWwpN90uOQMjKNFaZ8priucmYMOk,47908
337
+ arelle/plugin/validate/EDINET/rules/upload.py,sha256=YdjVIRTO9Zrmdprx-y0uo6MzHP7YLYYItwbR8AjP_fE,48731
338
338
  arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
339
339
  arelle/plugin/validate/ESEF/Dimensions.py,sha256=MOJM7vwNPEmV5cu-ZzPrhx3347ZvxgD6643OB2HRnIk,10597
340
340
  arelle/plugin/validate/ESEF/Util.py,sha256=QH3btcGqBpr42M7WSKZLSdNXygZaZLfEiEjlxoG21jE,7950
@@ -684,9 +684,9 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
684
684
  arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
685
685
  arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
686
686
  arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
687
- arelle_release-2.37.59.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
688
- arelle_release-2.37.59.dist-info/METADATA,sha256=wh7XkuU_1WbVuQhpnKA9ybkP_WlbD4eKla0WJ_2md1E,9327
689
- arelle_release-2.37.59.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
690
- arelle_release-2.37.59.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
691
- arelle_release-2.37.59.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
692
- arelle_release-2.37.59.dist-info/RECORD,,
687
+ arelle_release-2.37.61.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
688
+ arelle_release-2.37.61.dist-info/METADATA,sha256=_DG9yzSHAuG1UQGwzEWLrLD4Ow0SU8Qojx592crUxU0,9327
689
+ arelle_release-2.37.61.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
690
+ arelle_release-2.37.61.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
691
+ arelle_release-2.37.61.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
692
+ arelle_release-2.37.61.dist-info/RECORD,,