-
Notifications
You must be signed in to change notification settings - Fork 2
/
xbrl.py
83 lines (70 loc) · 2.77 KB
/
xbrl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import re
import json
from dataclasses import dataclass, field
import datetime as dt
@dataclass
class Report:
file_path: str
data: dict = field(init=False)
entity_name: str = field(init=False)
entity_description: str = field(init=False)
currency: str = field(init=False)
def __post_init__(self):
with open(self.file_path, "r", encoding="utf-8") as f:
self.data = json.load(f)
self.entity_name = self.get_all_facts(
"NameOfReportingEntityOrOtherMeansOfIdentification"
)[0]["value"].strip()
self.currency = self.get_all_facts("Revenue")[0]["unit"]
self.entity_description = self.get_all_facts(
"DescriptionOfNatureOfEntitysOperationsAndPrincipalActivities"
)[0]["value"].strip()
@staticmethod
def _to_float(value):
try:
return float(value)
except ValueError:
return value
@staticmethod
def _pascalcase_to_words(pascal_string):
words = re.findall("[A-Z][a-z]*", pascal_string)
return " ".join(words).capitalize()
def get_all_facts(self, concept: str, subcomponent=False) -> list:
records = []
x = 0
for key, fact in self.data["facts"].items():
field = {
"value": Report._to_float(fact["value"]),
"unit": fact["dimensions"]["unit"].split(":")[1]
if fact["dimensions"].get("unit")
else None,
"period_start": dt.datetime.fromisoformat(
fact["dimensions"]["period"].split("/")[0]
),
"period_end": dt.datetime.fromisoformat(
fact["dimensions"]["period"].split("/")[1]
)
if len(fact["dimensions"]["period"].split("/")) == 2
else None,
}
if subcomponent and any(
key == f"ifrs-full:{concept}" for key in fact["dimensions"]
):
field["name"] = self._pascalcase_to_words(
fact["dimensions"][f"ifrs-full:{concept}"].replace("ifrs-full:", "")
)
records.append(field)
elif fact["dimensions"]["concept"] == f"ifrs-full:{concept}":
field["name"]: fact["dimensions"]["concept"]
records.append(field)
return records
def get_latest_fact(self, concept: str) -> dict:
facts = self.get_all_facts(concept)
return max(facts, key=lambda x: x["period_start"])
def get_total_value(self, concept, period_start):
facts = self.get_all_facts(concept, True)
total_value = 0
for fact in facts:
if fact["period_start"] == period_start:
total_value += fact["value"]
return total_value