tricc-oo 1.5.22__py3-none-any.whl → 1.5.24__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.
Files changed (45) hide show
  1. tests/build.py +17 -23
  2. tests/test_cql.py +37 -108
  3. tests/to_ocl.py +15 -17
  4. tricc_oo/__init__.py +0 -6
  5. tricc_oo/converters/codesystem_to_ocl.py +51 -40
  6. tricc_oo/converters/cql/cqlLexer.py +1 -0
  7. tricc_oo/converters/cql/cqlListener.py +1 -0
  8. tricc_oo/converters/cql/cqlParser.py +1 -0
  9. tricc_oo/converters/cql/cqlVisitor.py +1 -0
  10. tricc_oo/converters/cql_to_operation.py +125 -123
  11. tricc_oo/converters/datadictionnary.py +45 -54
  12. tricc_oo/converters/drawio_type_map.py +143 -61
  13. tricc_oo/converters/tricc_to_xls_form.py +14 -24
  14. tricc_oo/converters/utils.py +3 -3
  15. tricc_oo/converters/xml_to_tricc.py +286 -231
  16. tricc_oo/models/__init__.py +2 -1
  17. tricc_oo/models/base.py +300 -308
  18. tricc_oo/models/calculate.py +63 -49
  19. tricc_oo/models/lang.py +26 -27
  20. tricc_oo/models/ocl.py +146 -161
  21. tricc_oo/models/ordered_set.py +15 -19
  22. tricc_oo/models/tricc.py +145 -89
  23. tricc_oo/parsers/xml.py +15 -30
  24. tricc_oo/serializers/planuml.py +4 -6
  25. tricc_oo/serializers/xls_form.py +81 -135
  26. tricc_oo/strategies/input/base_input_strategy.py +28 -32
  27. tricc_oo/strategies/input/drawio.py +59 -71
  28. tricc_oo/strategies/output/base_output_strategy.py +142 -67
  29. tricc_oo/strategies/output/fhir_form.py +377 -0
  30. tricc_oo/strategies/output/html_form.py +224 -0
  31. tricc_oo/strategies/output/openmrs_form.py +647 -0
  32. tricc_oo/strategies/output/spice.py +106 -127
  33. tricc_oo/strategies/output/xls_form.py +263 -222
  34. tricc_oo/strategies/output/xlsform_cdss.py +623 -142
  35. tricc_oo/strategies/output/xlsform_cht.py +108 -115
  36. tricc_oo/strategies/output/xlsform_cht_hf.py +13 -24
  37. tricc_oo/visitors/tricc.py +1297 -1016
  38. tricc_oo/visitors/utils.py +16 -16
  39. tricc_oo/visitors/xform_pd.py +91 -89
  40. {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/METADATA +127 -84
  41. tricc_oo-1.5.24.dist-info/RECORD +50 -0
  42. tricc_oo-1.5.24.dist-info/licenses/LICENSE +373 -0
  43. tricc_oo-1.5.22.dist-info/RECORD +0 -46
  44. {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/WHEEL +0 -0
  45. {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/top_level.txt +0 -0
@@ -1,19 +1,18 @@
1
-
1
+ from typing import List, Optional, Union
2
2
  import logging
3
- import random
4
- import string
5
- from enum import Enum, auto
6
- from typing import Dict, ForwardRef, List, Optional, Union
3
+ from tricc_oo.models.base import (
4
+ TriccBaseModel, TriccOperation, TriccStatic, TriccReference, Expression, TriccNodeType
5
+ )
7
6
 
8
- from pydantic import BaseModel, constr
9
- from strenum import StrEnum
10
- from .base import *
11
- from .tricc import *
12
- from tricc_oo.converters.utils import generate_id, get_rand_name
7
+ from tricc_oo.models.tricc import (
8
+ TriccNodeCalculateBase, TriccNodeBaseModel,
9
+ )
13
10
 
11
+ from tricc_oo.converters.utils import get_rand_name
14
12
 
15
-
13
+ logger = logging.getLogger(__name__)
16
14
 
15
+ ACTIVITY_END_NODE_FORMAT = "aend_{}"
17
16
 
18
17
 
19
18
  class TriccNodeDisplayCalculateBase(TriccNodeCalculateBase):
@@ -22,61 +21,72 @@ class TriccNodeDisplayCalculateBase(TriccNodeCalculateBase):
22
21
  help: Optional[str] = None # for diagnostic display
23
22
  trigger: Optional[Union[Expression, TriccOperation, TriccReference]] = None
24
23
  applicability: Optional[Union[Expression, TriccOperation, TriccReference]] = None
24
+
25
25
  # no need to copy save
26
26
  def to_fake(self):
27
27
  data = vars(self)
28
- del data['hint']
29
- del data['help']
30
- del data['save']
28
+ del data["hint"]
29
+ del data["help"]
30
+ del data["save"]
31
31
  fake = TriccNodeFakeCalculateBase(**data)
32
- replace_node(self,fake)
32
+ self.replace_node(fake)
33
33
  return fake
34
+
34
35
  def __str__(self):
35
36
  return self.get_name()
36
37
 
37
38
  def __repr__(self):
38
39
  return self.get_name()
39
-
40
+
41
+
40
42
  class TriccNodeCalculate(TriccNodeDisplayCalculateBase):
41
43
  tricc_type: TriccNodeType = TriccNodeType.calculate
44
+ remote_reference: Optional[Union[Expression, TriccOperation, TriccReference]] = None
42
45
 
43
46
 
44
47
  class TriccNodeAdd(TriccNodeDisplayCalculateBase):
45
48
  tricc_type: TriccNodeType = TriccNodeType.add
46
- datatype: str = 'number'
49
+ datatype: str = "number"
47
50
 
48
51
 
49
52
  class TriccNodeCount(TriccNodeDisplayCalculateBase):
50
53
  tricc_type: TriccNodeType = TriccNodeType.count
51
- datatype: str = 'number'
54
+ datatype: str = "number"
52
55
 
53
56
 
54
57
  class TriccNodeProposedDiagnosis(TriccNodeDisplayCalculateBase):
55
58
  tricc_type: TriccNodeType = TriccNodeType.proposed_diagnosis
56
59
  severity: str = None
57
-
58
-
60
+ remote_reference: Optional[Union[Expression, TriccOperation, TriccReference]] = None
61
+
62
+
59
63
  class TriccNodeFakeCalculateBase(TriccNodeCalculateBase):
60
64
  ...
61
65
 
66
+
62
67
  class TriccNodeInput(TriccNodeFakeCalculateBase):
63
68
  tricc_type: TriccNodeType = TriccNodeType.input
64
-
69
+
70
+
65
71
  class TriccNodeDisplayBridge(TriccNodeDisplayCalculateBase):
66
72
  tricc_type: TriccNodeType = TriccNodeType.bridge
67
-
73
+
68
74
 
69
75
  class TriccNodeBridge(TriccNodeFakeCalculateBase):
70
76
  tricc_type: TriccNodeType = TriccNodeType.bridge
71
-
72
- class TriccRhombusMixIn():
73
-
77
+
78
+
79
+ class TriccRhombusMixIn:
80
+
74
81
  def make_mixin_instance(self, instance, instance_nb, activity, **kwargs):
75
82
  # shallow copy
76
83
  reference = []
77
84
  expression_reference = None
78
85
  instance.path = None
79
- if isinstance(self.expression_reference, (str, TriccOperation, TriccReference, TriccStatic)):
86
+ if isinstance(
87
+ self.expression_reference,
88
+ (str, TriccOperation, TriccReference, TriccStatic),
89
+ ):
80
90
  expression_reference = self.expression_reference.copy()
81
91
  reference = list(expression_reference.get_references())
82
92
  if isinstance(self.reference, (str, TriccOperation, TriccReference, TriccStatic)):
@@ -108,42 +118,46 @@ class TriccRhombusMixIn():
108
118
  return instance
109
119
 
110
120
 
111
-
112
-
113
- class TriccNodeRhombus(TriccNodeCalculateBase,TriccRhombusMixIn):
121
+ class TriccNodeRhombus(TriccNodeCalculateBase, TriccRhombusMixIn):
114
122
  tricc_type: TriccNodeType = TriccNodeType.rhombus
115
123
  path: Optional[TriccNodeBaseModel] = None
116
- reference: Union[List[TriccNodeBaseModel], Expression, TriccOperation, TriccReference, List[TriccReference]]
117
-
124
+ reference: Union[
125
+ List[TriccNodeBaseModel],
126
+ Expression,
127
+ TriccOperation,
128
+ TriccReference,
129
+ List[TriccReference],
130
+ ]
131
+ remote_reference: Optional[Union[Expression, TriccOperation, TriccReference]] = None
132
+
118
133
  def make_instance(self, instance_nb, activity, **kwargs):
119
134
  instance = super(TriccNodeRhombus, self).make_instance(instance_nb, activity, **kwargs)
120
135
  instance = self.make_mixin_instance(instance, instance_nb, activity, **kwargs)
121
136
  return instance
122
137
 
123
-
124
138
  def __init__(self, **data):
125
- data['name'] = get_rand_name(data.get('id', None))
139
+ data["name"] = get_rand_name(data.get("id", None))
126
140
  super().__init__(**data)
127
141
 
128
142
 
129
-
130
-
131
-
132
143
  class TriccNodeDiagnosis(TriccNodeDisplayCalculateBase):
133
144
  tricc_type: TriccNodeType = TriccNodeType.diagnosis
134
145
  severity: str = None
146
+
135
147
  def __init__(self, **data):
136
- data['reference'] = f'"final.{data["name"]}" is true'
148
+ data["reference"] = f'"final.{data["name"]}" is true'
137
149
  super().__init__(**data)
138
150
 
139
151
  # rename rhombus
140
152
  self.name = get_rand_name(f"d{data.get('id', None)}")
141
153
 
154
+
142
155
  class TriccNodeExclusive(TriccNodeFakeCalculateBase):
143
156
  tricc_type: TriccNodeType = TriccNodeType.exclusive
144
157
 
158
+
145
159
  def get_node_from_id(activity, node, edge_only):
146
- node_id = getattr(node,'id',node)
160
+ node_id = getattr(node, "id", node)
147
161
  if not isinstance(node_id, str):
148
162
  logger.critical("can set prev_next only with string or node")
149
163
  exit(1)
@@ -152,15 +166,16 @@ def get_node_from_id(activity, node, edge_only):
152
166
  elif node_id in activity.nodes:
153
167
  node = activity.nodes[node_id]
154
168
  elif not edge_only:
155
- logger.critical(f"cannot find {node_id} in {activiy.get_name()}")
169
+ logger.critical(f"cannot find {node_id} in {activity.get_name()}")
156
170
  exit(1)
157
171
  return node_id, node
158
172
 
173
+
159
174
  class TriccNodeWait(TriccNodeFakeCalculateBase, TriccRhombusMixIn):
160
175
  tricc_type: TriccNodeType = TriccNodeType.wait
161
176
  path: Optional[TriccNodeBaseModel] = None
162
177
  reference: Union[List[TriccNodeBaseModel], Expression, TriccOperation]
163
-
178
+
164
179
  def make_instance(self, instance_nb, activity, **kwargs):
165
180
  instance = super(TriccNodeWait, self).make_instance(instance_nb, activity, **kwargs)
166
181
  instance = self.make_mixin_instance(instance, instance_nb, activity, **kwargs)
@@ -183,21 +198,21 @@ class TriccNodeEnd(TriccNodeDisplayCalculateBase):
183
198
  tricc_type: TriccNodeType = TriccNodeType.end
184
199
  process: str = None
185
200
  priority: int = 1000
201
+
186
202
  def __init__(self, **data):
187
- if data.get('name', None) is None:
188
- data['name'] = 'tricc_end_' + data.get('process', '')
203
+ if data.get("name", None) is None:
204
+ data["name"] = "tricc_end_" + data.get("process", "")
189
205
  super().__init__(**data)
190
206
  # FOR END
191
-
192
-
193
207
 
194
208
  def set_name(self):
195
209
  if self.name is None:
196
210
  self.name = self.get_reference()
197
- #self.name = END_NODE_FORMAT.format(self.activity.id)
211
+ # self.name = END_NODE_FORMAT.format(self.activity.id)
198
212
 
199
213
  def get_reference(self):
200
- return 'tricc_end_' + (self.process or '')
214
+ return "tricc_end_" + (self.process or "")
215
+
201
216
 
202
217
  class TriccNodeActivityStart(TriccNodeFakeCalculateBase):
203
218
  tricc_type: TriccNodeType = TriccNodeType.activity_start
@@ -209,11 +224,10 @@ def get_node_from_list(in_nodes, node_id):
209
224
  if len(nodes) > 0:
210
225
  return nodes[0]
211
226
 
227
+
212
228
  # qualculate that saves quantity, or we may merge integer/decimals
213
229
  class TriccNodeQuantity(TriccNodeDisplayCalculateBase):
214
230
  tricc_type: TriccNodeType = TriccNodeType.quantity
215
231
 
216
232
 
217
-
218
-
219
- TriccNodeCalculate.update_forward_refs()
233
+ TriccNodeCalculate.update_forward_refs()
tricc_oo/models/lang.py CHANGED
@@ -5,21 +5,21 @@ class SingletonLangClass(object):
5
5
  languages = None
6
6
  entries = []
7
7
  po_file = None
8
-
8
+
9
9
  def __init__(self):
10
10
  self.po_file = POFile()
11
-
11
+
12
12
  def __new__(self):
13
- if not hasattr(self, 'instance'):
13
+ if not hasattr(self, "instance"):
14
14
  self.instance = super(SingletonLangClass, self).__new__(self)
15
15
  return self.instance
16
-
16
+
17
17
  def add_trad(self, code, lang):
18
18
  if self.languages is None:
19
19
  self.languages = {}
20
20
  self.languages[code] = lang
21
-
22
- def get_trads(self, message, force_dict = False,trad=None):
21
+
22
+ def get_trads(self, message, force_dict=False, trad=None):
23
23
  if isinstance(message, dict):
24
24
  if force_dict:
25
25
  return message
@@ -27,46 +27,45 @@ class SingletonLangClass(object):
27
27
  return message[trad]
28
28
  return list(message.values())[0]
29
29
  message = message.strip()
30
- if message == '' and (self.languages is None or trad is not None):
30
+ if message == "" and (self.languages is None or trad is not None):
31
31
  if force_dict:
32
- return {'default': ''}
33
- else :
34
- return ''
35
-
32
+ return {"default": ""}
33
+ else:
34
+ return ""
35
+
36
36
  if message not in self.entries:
37
- self.po_file.insert(0,POEntry(msgid = message))
37
+ self.po_file.insert(0, POEntry(msgid=message))
38
38
  self.entries.append(message)
39
-
39
+
40
40
  if self.languages is None or len(self.languages) == 0:
41
41
  if force_dict:
42
- return {'default': message}
43
- else :
42
+ return {"default": message}
43
+ else:
44
44
  return message
45
45
  elif trad is not None:
46
- return self.languages[trad].gettext(message) if len(message)>0 else ''
46
+ return self.languages[trad].gettext(message) if len(message) > 0 else ""
47
47
  else:
48
48
  trads = {}
49
49
  for code, lang in self.languages.items():
50
- trads[code]= lang.gettext(message) if len(message)>0 else ''
50
+ trads[code] = lang.gettext(message) if len(message) > 0 else ""
51
51
  return trads
52
52
 
53
53
  def get_trads_map(self, col):
54
54
  if self.languages is None:
55
- return {col:col}
55
+ return {col: col}
56
56
  else:
57
57
  map = {}
58
58
  for code, lang in self.languages.items():
59
- map[col+'::'+code] = col+'['+code+']'
60
-
61
- return map
59
+ map[col + "::" + code] = col + "[" + code + "]"
62
60
 
63
- def join_trads(trads_1, trads_2, separator= ' '):
61
+ return map
62
+
63
+ def join_trads(trads_1, trads_2, separator=" "):
64
64
  dict_3 = {**trads_1, **trads_1}
65
65
  for key, value in dict_3.items():
66
66
  if key in trads_1 and key in trads_2:
67
- dict_3[key] = value + separator + trads_1[key]
68
- return dict_3
69
-
67
+ dict_3[key] = value + separator + trads_1[key]
68
+ return dict_3
69
+
70
70
  def to_po_file(self, path):
71
- self.po_file.save(fpath = path)
72
-
71
+ self.po_file.save(fpath=path)