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.
- tests/build.py +17 -23
- tests/test_cql.py +37 -108
- tests/to_ocl.py +15 -17
- tricc_oo/__init__.py +0 -6
- tricc_oo/converters/codesystem_to_ocl.py +51 -40
- tricc_oo/converters/cql/cqlLexer.py +1 -0
- tricc_oo/converters/cql/cqlListener.py +1 -0
- tricc_oo/converters/cql/cqlParser.py +1 -0
- tricc_oo/converters/cql/cqlVisitor.py +1 -0
- tricc_oo/converters/cql_to_operation.py +125 -123
- tricc_oo/converters/datadictionnary.py +45 -54
- tricc_oo/converters/drawio_type_map.py +143 -61
- tricc_oo/converters/tricc_to_xls_form.py +14 -24
- tricc_oo/converters/utils.py +3 -3
- tricc_oo/converters/xml_to_tricc.py +286 -231
- tricc_oo/models/__init__.py +2 -1
- tricc_oo/models/base.py +300 -308
- tricc_oo/models/calculate.py +63 -49
- tricc_oo/models/lang.py +26 -27
- tricc_oo/models/ocl.py +146 -161
- tricc_oo/models/ordered_set.py +15 -19
- tricc_oo/models/tricc.py +145 -89
- tricc_oo/parsers/xml.py +15 -30
- tricc_oo/serializers/planuml.py +4 -6
- tricc_oo/serializers/xls_form.py +81 -135
- tricc_oo/strategies/input/base_input_strategy.py +28 -32
- tricc_oo/strategies/input/drawio.py +59 -71
- tricc_oo/strategies/output/base_output_strategy.py +142 -67
- tricc_oo/strategies/output/fhir_form.py +377 -0
- tricc_oo/strategies/output/html_form.py +224 -0
- tricc_oo/strategies/output/openmrs_form.py +647 -0
- tricc_oo/strategies/output/spice.py +106 -127
- tricc_oo/strategies/output/xls_form.py +263 -222
- tricc_oo/strategies/output/xlsform_cdss.py +623 -142
- tricc_oo/strategies/output/xlsform_cht.py +108 -115
- tricc_oo/strategies/output/xlsform_cht_hf.py +13 -24
- tricc_oo/visitors/tricc.py +1297 -1016
- tricc_oo/visitors/utils.py +16 -16
- tricc_oo/visitors/xform_pd.py +91 -89
- {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/METADATA +127 -84
- tricc_oo-1.5.24.dist-info/RECORD +50 -0
- tricc_oo-1.5.24.dist-info/licenses/LICENSE +373 -0
- tricc_oo-1.5.22.dist-info/RECORD +0 -46
- {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/WHEEL +0 -0
- {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.24.dist-info}/top_level.txt +0 -0
|
@@ -1,14 +1,56 @@
|
|
|
1
|
+
import html2text
|
|
2
|
+
import logging
|
|
1
3
|
import base64
|
|
2
4
|
import os
|
|
3
5
|
import re
|
|
4
|
-
from curses.ascii import isalnum, isalpha, isdigit
|
|
5
6
|
|
|
6
|
-
from numpy import isnan
|
|
7
7
|
|
|
8
|
-
from tricc_oo.converters.utils import
|
|
8
|
+
from tricc_oo.converters.utils import remove_html, clean_str
|
|
9
9
|
from tricc_oo.converters.cql_to_operation import transform_cql_to_operation
|
|
10
|
-
from tricc_oo.
|
|
11
|
-
from tricc_oo.models.base import
|
|
10
|
+
from tricc_oo.converters.utils import generate_id, get_rand_name
|
|
11
|
+
from tricc_oo.models.base import (
|
|
12
|
+
TriccOperator, TriccOperation,
|
|
13
|
+
TriccStatic, TriccReference, TriccNodeType, TriccEdge, OPERATION_LIST
|
|
14
|
+
)
|
|
15
|
+
from tricc_oo.models.calculate import (
|
|
16
|
+
TriccNodeDisplayBridge,
|
|
17
|
+
TriccNodeBridge,
|
|
18
|
+
TriccNodeActivityEnd,
|
|
19
|
+
TriccNodeActivityStart,
|
|
20
|
+
TriccNodeEnd,
|
|
21
|
+
TriccNodeCalculate,
|
|
22
|
+
TriccNodeRhombus,
|
|
23
|
+
TriccNodeDisplayCalculateBase,
|
|
24
|
+
TriccNodeExclusive,
|
|
25
|
+
TriccNodeProposedDiagnosis,
|
|
26
|
+
TriccNodeDiagnosis,
|
|
27
|
+
TriccRhombusMixIn,
|
|
28
|
+
TriccNodeInput,
|
|
29
|
+
|
|
30
|
+
)
|
|
31
|
+
from tricc_oo.models.tricc import (
|
|
32
|
+
TriccNodeCalculateBase,
|
|
33
|
+
TriccNodeMainStart,
|
|
34
|
+
TriccNodeActivity,
|
|
35
|
+
TriccGroup,
|
|
36
|
+
TriccNodeSelect,
|
|
37
|
+
TriccNodeGoTo,
|
|
38
|
+
TriccNodeSelectMultiple,
|
|
39
|
+
TriccNodeInputModel,
|
|
40
|
+
TriccNodeSelectNotAvailable,
|
|
41
|
+
TriccNodeSelectOption,
|
|
42
|
+
TriccNodeDisplayModel,
|
|
43
|
+
TriccNodeMoreInfo,
|
|
44
|
+
TriccNodeText,
|
|
45
|
+
TriccNodeDecimal,
|
|
46
|
+
TriccNodeInteger,
|
|
47
|
+
TriccNodeDate,
|
|
48
|
+
TriccNodeSelectOne,
|
|
49
|
+
TriccNodeSelectYesNo,
|
|
50
|
+
TriccNodeNote,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
12
54
|
from tricc_oo.models.ocl import get_data_type
|
|
13
55
|
from tricc_oo.converters.drawio_type_map import TYPE_MAP
|
|
14
56
|
from tricc_oo.parsers.xml import (
|
|
@@ -20,7 +62,11 @@ from tricc_oo.parsers.xml import (
|
|
|
20
62
|
get_tricc_type_list,
|
|
21
63
|
)
|
|
22
64
|
import hashlib
|
|
23
|
-
from tricc_oo.visitors.tricc import
|
|
65
|
+
from tricc_oo.visitors.tricc import (
|
|
66
|
+
get_select_yes_no_options, get_select_not_available_options,
|
|
67
|
+
set_prev_next_node, inject_node_before,
|
|
68
|
+
merge_node, remove_prev_next, get_activity_wait, get_count_terms_details
|
|
69
|
+
)
|
|
24
70
|
from tricc_oo.converters.datadictionnary import add_concept
|
|
25
71
|
|
|
26
72
|
TRICC_YES_LABEL = ["yes", "oui"]
|
|
@@ -28,15 +74,9 @@ TRICC_NO_LABEL = ["no", "non"]
|
|
|
28
74
|
TRICC_FOLLOW_LABEL = ["follow", "suivre", "continue"]
|
|
29
75
|
NO_LABEL = "NO_LABEL"
|
|
30
76
|
TRICC_LIST_NAME = "list_{0}"
|
|
31
|
-
import logging
|
|
32
|
-
DISPLAY_ATTRIBUTES = [
|
|
33
|
-
'label',
|
|
34
|
-
'hint',
|
|
35
|
-
'help'
|
|
36
|
-
]
|
|
37
|
-
logger = logging.getLogger("default")
|
|
38
|
-
import html2text
|
|
39
77
|
|
|
78
|
+
DISPLAY_ATTRIBUTES = ["label", "hint", "help"]
|
|
79
|
+
logger = logging.getLogger("default")
|
|
40
80
|
|
|
41
81
|
|
|
42
82
|
def get_all_nodes(diagram, activity, nodes):
|
|
@@ -51,15 +91,16 @@ def get_all_nodes(diagram, activity, nodes):
|
|
|
51
91
|
activity,
|
|
52
92
|
attributes=TYPE_MAP[tricc_type]["attributes"],
|
|
53
93
|
mandatory_attributes=TYPE_MAP[tricc_type]["mandatory_attributes"],
|
|
54
|
-
has_options=TYPE_MAP[tricc_type].get(
|
|
94
|
+
has_options=TYPE_MAP[tricc_type].get("has_options", None),
|
|
55
95
|
)
|
|
56
96
|
|
|
57
97
|
return nodes
|
|
58
98
|
|
|
99
|
+
|
|
59
100
|
def create_activity(diagram, media_path, project):
|
|
60
101
|
|
|
61
102
|
external_id = diagram.attrib.get("id")
|
|
62
|
-
id = get_id(
|
|
103
|
+
id = get_id(external_id, diagram.attrib.get("id"))
|
|
63
104
|
root = create_root_node(diagram)
|
|
64
105
|
name = diagram.attrib.get("name")
|
|
65
106
|
form_id = diagram.attrib.get("name", None)
|
|
@@ -73,7 +114,7 @@ def create_activity(diagram, media_path, project):
|
|
|
73
114
|
form_id=form_id,
|
|
74
115
|
)
|
|
75
116
|
if root.relevance is not None:
|
|
76
|
-
activity.applicability=root.relevance
|
|
117
|
+
activity.applicability = root.relevance
|
|
77
118
|
# activity definition is never instanciated
|
|
78
119
|
if isinstance(root, TriccNodeActivityStart):
|
|
79
120
|
activity.instance = 0
|
|
@@ -85,21 +126,45 @@ def create_activity(diagram, media_path, project):
|
|
|
85
126
|
activity.edges = edges
|
|
86
127
|
nodes = get_nodes(diagram, activity)
|
|
87
128
|
for n in nodes.values():
|
|
88
|
-
|
|
129
|
+
|
|
89
130
|
if (
|
|
90
|
-
issubclass(n.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase))
|
|
131
|
+
issubclass(n.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase))
|
|
91
132
|
and not isinstance(n, (TriccRhombusMixIn, TriccNodeRhombus, TriccNodeDisplayBridge))
|
|
92
|
-
and not n.name.startswith(
|
|
133
|
+
and not n.name.startswith("label_")
|
|
93
134
|
):
|
|
94
|
-
system = n.name.split(
|
|
135
|
+
system = n.name.split(".")[0] if "." in n.name else "tricc"
|
|
95
136
|
if isinstance(n, TriccNodeSelectOption) and isinstance(n.select, TriccNodeSelectNotAvailable):
|
|
96
|
-
add_concept(
|
|
137
|
+
add_concept(
|
|
138
|
+
project.code_systems,
|
|
139
|
+
system,
|
|
140
|
+
n.select.name,
|
|
141
|
+
n.label,
|
|
142
|
+
{"datatype": "Boolean", "contextType": get_context_type(n)},
|
|
143
|
+
)
|
|
97
144
|
elif not isinstance(n, TriccNodeSelectNotAvailable):
|
|
98
|
-
add_concept(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
145
|
+
add_concept(
|
|
146
|
+
project.code_systems,
|
|
147
|
+
system,
|
|
148
|
+
n.name,
|
|
149
|
+
n.label,
|
|
150
|
+
{
|
|
151
|
+
"datatype": get_data_type(n.tricc_type),
|
|
152
|
+
"contextType": get_context_type(n),
|
|
153
|
+
},
|
|
154
|
+
)
|
|
155
|
+
if getattr(n, "save", None):
|
|
156
|
+
system = n.save.split(".")[0] if "." in n.save else "tricc"
|
|
157
|
+
add_concept(
|
|
158
|
+
project.code_systems,
|
|
159
|
+
system,
|
|
160
|
+
n.save,
|
|
161
|
+
n.label,
|
|
162
|
+
{
|
|
163
|
+
"datatype": get_data_type(n.tricc_type),
|
|
164
|
+
"contextType": get_context_type(n),
|
|
165
|
+
},
|
|
166
|
+
)
|
|
167
|
+
|
|
103
168
|
groups = get_groups(diagram, nodes, activity)
|
|
104
169
|
if groups and len(groups) > 0:
|
|
105
170
|
activity.groups = groups
|
|
@@ -110,7 +175,7 @@ def create_activity(diagram, media_path, project):
|
|
|
110
175
|
# link back the activity
|
|
111
176
|
activity.root.activity = activity
|
|
112
177
|
manage_dangling_calculate(activity)
|
|
113
|
-
|
|
178
|
+
|
|
114
179
|
if activity is not None:
|
|
115
180
|
if activity.root is not None:
|
|
116
181
|
project.pages[activity.id] = activity
|
|
@@ -119,7 +184,7 @@ def create_activity(diagram, media_path, project):
|
|
|
119
184
|
activity.root.process == "main" or activity.root.process is None
|
|
120
185
|
):
|
|
121
186
|
project.start_pages["main"] = activity
|
|
122
|
-
activity.root.process =
|
|
187
|
+
activity.root.process = "main"
|
|
123
188
|
elif activity.root.process is not None:
|
|
124
189
|
if activity.root.process not in project.start_pages:
|
|
125
190
|
project.start_pages[activity.root.process] = []
|
|
@@ -127,24 +192,27 @@ def create_activity(diagram, media_path, project):
|
|
|
127
192
|
else:
|
|
128
193
|
logger.warning(
|
|
129
194
|
"Page {0} has a start node but there is already a start node in page {1}".format(
|
|
130
|
-
activity.label,
|
|
195
|
+
activity.label, project.start_pages[activity.root.process][0]
|
|
131
196
|
)
|
|
132
197
|
)
|
|
133
198
|
if images:
|
|
134
199
|
project.images += images
|
|
135
|
-
for node in list(
|
|
200
|
+
for node in list(
|
|
201
|
+
filter(
|
|
202
|
+
lambda p_node: isinstance(p_node, TriccNodeSelectNotAvailable),
|
|
203
|
+
list(activity.nodes.values()),
|
|
204
|
+
)
|
|
205
|
+
):
|
|
136
206
|
prev_node = None
|
|
137
|
-
prev_edges = list(filter(lambda p_e: p_e.target == node.id,list(activity.edges)))
|
|
207
|
+
prev_edges = list(filter(lambda p_e: p_e.target == node.id, list(activity.edges)))
|
|
138
208
|
if len(prev_edges):
|
|
139
209
|
prev_node = [n for n in activity.nodes.values() if n.id in [p_e.source for p_e in prev_edges]]
|
|
140
210
|
if prev_node:
|
|
141
211
|
node.parent = prev_node[0]
|
|
142
|
-
if not
|
|
212
|
+
if not node.parent:
|
|
143
213
|
logger.critical(f"unable to find the parent of the NotApplicable node {node.get_name()}")
|
|
144
214
|
exit(1)
|
|
145
215
|
|
|
146
|
-
|
|
147
|
-
|
|
148
216
|
else:
|
|
149
217
|
return None, None
|
|
150
218
|
logger.warning("root not found for page {0}".format(name))
|
|
@@ -158,10 +226,7 @@ def manage_dangling_calculate(activity):
|
|
|
158
226
|
for n in list(
|
|
159
227
|
filter(
|
|
160
228
|
lambda x: (x.target == node.id or x.target == node)
|
|
161
|
-
and (
|
|
162
|
-
x.source in activity.nodes
|
|
163
|
-
or x.source in activity.nodes.values()
|
|
164
|
-
),
|
|
229
|
+
and (x.source in activity.nodes or x.source in activity.nodes.values()),
|
|
165
230
|
activity.edges,
|
|
166
231
|
)
|
|
167
232
|
)
|
|
@@ -188,7 +253,9 @@ def process_edges(diagram, media_path, activity, nodes):
|
|
|
188
253
|
if image is not None:
|
|
189
254
|
images.append({"file_path": enriched, "image_content": image})
|
|
190
255
|
|
|
191
|
-
elif isinstance(nodes[edge.target], (TriccNodeActivityEnd)) or (
|
|
256
|
+
elif isinstance(nodes[edge.target], (TriccNodeActivityEnd)) or (
|
|
257
|
+
isinstance(nodes[edge.target], (TriccNodeEnd)) and isinstance(activity.root, TriccNodeMainStart)
|
|
258
|
+
):
|
|
192
259
|
end_found = True
|
|
193
260
|
if (
|
|
194
261
|
edge.target in nodes
|
|
@@ -197,19 +264,16 @@ def process_edges(diagram, media_path, activity, nodes):
|
|
|
197
264
|
):
|
|
198
265
|
edge.target = nodes[edge.target].path.id
|
|
199
266
|
# modify edge for selectyesNo
|
|
200
|
-
if edge.source in nodes and isinstance(
|
|
201
|
-
nodes[edge.source], TriccNodeSelectYesNo
|
|
202
|
-
):
|
|
267
|
+
if edge.source in nodes and isinstance(nodes[edge.source], TriccNodeSelectYesNo):
|
|
203
268
|
process_yesno_edge(edge, nodes)
|
|
204
269
|
|
|
205
270
|
# create calculate based on edges label
|
|
206
271
|
elif edge.value is not None:
|
|
207
272
|
label = edge.value.strip()
|
|
273
|
+
label_html_free = html2text.html2text(label)
|
|
208
274
|
processed = False
|
|
209
275
|
calc = None
|
|
210
|
-
if (
|
|
211
|
-
label.lower() in TRICC_FOLLOW_LABEL
|
|
212
|
-
):
|
|
276
|
+
if label.lower() in TRICC_FOLLOW_LABEL:
|
|
213
277
|
if isinstance(nodes[edge.source], TriccNodeRhombus):
|
|
214
278
|
edge.source = nodes[edge.source].path.id
|
|
215
279
|
edge.source_external_id = None
|
|
@@ -221,9 +285,12 @@ def process_edges(diagram, media_path, activity, nodes):
|
|
|
221
285
|
calc = process_factor_edge(edge, nodes)
|
|
222
286
|
elif label.lower() in TRICC_NO_LABEL:
|
|
223
287
|
calc = process_exclusive_edge(edge, nodes)
|
|
224
|
-
elif
|
|
288
|
+
elif any(
|
|
289
|
+
reserved in label_html_free
|
|
290
|
+
for reserved in ([str(o) for o in list(TriccOperator)] + list(OPERATION_LIST.keys()) + ["$this"])
|
|
291
|
+
):
|
|
225
292
|
# manage comment
|
|
226
|
-
calc = process_condition_edge(edge, nodes)
|
|
293
|
+
calc = process_condition_edge(edge, label_html_free, nodes)
|
|
227
294
|
else:
|
|
228
295
|
logger.warning(f"unsupported edge label {label} in {diagram.attrib.get('name', diagram.attrib['id'])}")
|
|
229
296
|
processed = True
|
|
@@ -242,25 +309,23 @@ def process_edges(diagram, media_path, activity, nodes):
|
|
|
242
309
|
"not management found",
|
|
243
310
|
)
|
|
244
311
|
)
|
|
245
|
-
elif edge.source in
|
|
246
|
-
logger.critical(
|
|
247
|
-
"rhombus {} node with labelless edges".format(nodes[edge.source].get_name())
|
|
248
|
-
)
|
|
312
|
+
elif edge.source in nodes and isinstance(nodes[edge.source], TriccNodeRhombus):
|
|
313
|
+
logger.critical("rhombus {} node with labelless edges".format(nodes[edge.source].get_name()))
|
|
249
314
|
if not end_found:
|
|
250
315
|
fake_end = TriccNodeActivityEnd(id=generate_id(f"e{activity.name}"), activity=activity, group=activity)
|
|
251
316
|
last_nodes = [
|
|
252
|
-
n
|
|
317
|
+
n
|
|
318
|
+
for n in list(activity.nodes.values())
|
|
253
319
|
if (
|
|
254
320
|
issubclass(
|
|
255
|
-
n.__class__,
|
|
321
|
+
n.__class__,
|
|
256
322
|
(
|
|
257
|
-
TriccNodeInputModel,
|
|
258
|
-
TriccNodeText,
|
|
323
|
+
TriccNodeInputModel,
|
|
324
|
+
TriccNodeText,
|
|
259
325
|
TriccNodeNote,
|
|
260
|
-
)
|
|
261
|
-
) and (
|
|
262
|
-
not any([n.id == e.source for e in activity.edges])
|
|
326
|
+
),
|
|
263
327
|
)
|
|
328
|
+
and (not any([n.id == e.source for e in activity.edges]))
|
|
264
329
|
)
|
|
265
330
|
]
|
|
266
331
|
if last_nodes:
|
|
@@ -271,10 +336,7 @@ def process_edges(diagram, media_path, activity, nodes):
|
|
|
271
336
|
else:
|
|
272
337
|
logger.warning(f"Activity {activity.label} have no end, calculated might be included in the end definition")
|
|
273
338
|
last_nodes = [
|
|
274
|
-
n for n in list(activity.nodes.values())
|
|
275
|
-
if (
|
|
276
|
-
not any([n.id == e.source for e in activity.edges])
|
|
277
|
-
)
|
|
339
|
+
n for n in list(activity.nodes.values()) if (not any([n.id == e.source for e in activity.edges]))
|
|
278
340
|
]
|
|
279
341
|
if last_nodes:
|
|
280
342
|
for n in last_nodes:
|
|
@@ -283,20 +345,19 @@ def process_edges(diagram, media_path, activity, nodes):
|
|
|
283
345
|
else:
|
|
284
346
|
logger.critical(f"cannot guess end for {activity.get_name()}")
|
|
285
347
|
exit(1)
|
|
286
|
-
|
|
348
|
+
|
|
287
349
|
return images
|
|
288
350
|
|
|
351
|
+
|
|
289
352
|
def get_id(elm_id, activity_id):
|
|
290
|
-
|
|
353
|
+
return str(elm_id) if len(elm_id) > 8 else str(activity_id) + str(elm_id)
|
|
354
|
+
|
|
291
355
|
|
|
292
356
|
def _get_name(name, id, act_id):
|
|
293
|
-
if (
|
|
294
|
-
name is not None
|
|
295
|
-
and (name.endswith(("_", ".")))
|
|
296
|
-
):
|
|
357
|
+
if name is not None and (name.endswith(("_", "."))):
|
|
297
358
|
return name + get_id(id, act_id)
|
|
298
359
|
return name
|
|
299
|
-
|
|
360
|
+
|
|
300
361
|
|
|
301
362
|
def get_nodes(diagram, activity):
|
|
302
363
|
nodes = {activity.root.id: activity.root}
|
|
@@ -304,12 +365,9 @@ def get_nodes(diagram, activity):
|
|
|
304
365
|
new_nodes = {}
|
|
305
366
|
node_to_remove = []
|
|
306
367
|
activity_end_node = None
|
|
307
|
-
end_node = None
|
|
308
368
|
for node in nodes.values():
|
|
309
369
|
# clean name
|
|
310
|
-
if (
|
|
311
|
-
hasattr(node, "name")
|
|
312
|
-
):
|
|
370
|
+
if hasattr(node, "name"):
|
|
313
371
|
node.name = _get_name(node.name, node.id, activity.id)
|
|
314
372
|
if issubclass(node.__class__, TriccRhombusMixIn) and node.path is None:
|
|
315
373
|
# generate rhombuse path
|
|
@@ -331,12 +389,10 @@ def get_nodes(diagram, activity):
|
|
|
331
389
|
next_nodes_id = [e.target for e in activity.edges if e.source == node.id]
|
|
332
390
|
if len(next_nodes_id) > 0:
|
|
333
391
|
|
|
334
|
-
calc = get_activity_wait(
|
|
335
|
-
path, [node], next_nodes_id, node, edge_only=True
|
|
336
|
-
)
|
|
392
|
+
calc = get_activity_wait(path, [node], next_nodes_id, node, edge_only=True)
|
|
337
393
|
new_nodes[calc.id] = calc
|
|
338
394
|
for goto_next_node in next_nodes_id:
|
|
339
|
-
remove_prev_next(node, goto_next_node, activity)
|
|
395
|
+
remove_prev_next(node, goto_next_node, activity)
|
|
340
396
|
elif isinstance(node, TriccNodeActivityEnd):
|
|
341
397
|
if not activity_end_node:
|
|
342
398
|
activity_end_node = node
|
|
@@ -345,12 +401,11 @@ def get_nodes(diagram, activity):
|
|
|
345
401
|
node_to_remove.append(node.id)
|
|
346
402
|
# add activity relevance to calculate
|
|
347
403
|
elif (
|
|
348
|
-
issubclass(node.__class__, TriccNodeDisplayCalculateBase)
|
|
349
|
-
and not getattr(node,
|
|
404
|
+
issubclass(node.__class__, TriccNodeDisplayCalculateBase)
|
|
405
|
+
and not getattr(node, "relevance", None)
|
|
350
406
|
and node.activity.applicability
|
|
351
407
|
):
|
|
352
408
|
node.applicability = node.activity.applicability
|
|
353
|
-
|
|
354
409
|
|
|
355
410
|
nodes.update(new_nodes)
|
|
356
411
|
|
|
@@ -371,7 +426,7 @@ def create_root_node(diagram):
|
|
|
371
426
|
elm = get_tricc_type(diagram, "UserObject", TriccNodeType.start)
|
|
372
427
|
if elm is not None:
|
|
373
428
|
external_id = elm.attrib.get("id")
|
|
374
|
-
id = get_id(
|
|
429
|
+
id = get_id(external_id, diagram.attrib.get("id"))
|
|
375
430
|
node = TriccNodeMainStart(
|
|
376
431
|
id=id,
|
|
377
432
|
external_id=external_id,
|
|
@@ -380,7 +435,7 @@ def create_root_node(diagram):
|
|
|
380
435
|
label=elm.attrib.get("label"),
|
|
381
436
|
form_id=elm.attrib.get("form_id"),
|
|
382
437
|
relevance=elm.attrib.get("relevance"),
|
|
383
|
-
process=elm.attrib.get(
|
|
438
|
+
process=elm.attrib.get("process", "registration"),
|
|
384
439
|
)
|
|
385
440
|
else:
|
|
386
441
|
elm = get_tricc_type(diagram, "object", TriccNodeType.activity_start)
|
|
@@ -388,19 +443,15 @@ def create_root_node(diagram):
|
|
|
388
443
|
elm = get_tricc_type(diagram, "UserObject", TriccNodeType.activity_start)
|
|
389
444
|
if elm is not None:
|
|
390
445
|
external_id = elm.attrib.get("id")
|
|
391
|
-
id = get_id(
|
|
446
|
+
id = get_id(external_id, diagram.attrib.get("id"))
|
|
392
447
|
node = TriccNodeActivityStart(
|
|
393
448
|
id=id,
|
|
394
449
|
external_id=external_id,
|
|
395
|
-
#parent=elm.attrib.get("parent"),
|
|
450
|
+
# parent=elm.attrib.get("parent"),
|
|
396
451
|
name="ma" + id,
|
|
397
452
|
label=diagram.attrib.get("name"),
|
|
398
453
|
relevance=elm.attrib.get("relevance"),
|
|
399
|
-
instance=int(
|
|
400
|
-
elm.attrib.get("instance")
|
|
401
|
-
if elm.attrib.get("instance") is not None
|
|
402
|
-
else 1
|
|
403
|
-
),
|
|
454
|
+
instance=int(elm.attrib.get("instance") if elm.attrib.get("instance") is not None else 1),
|
|
404
455
|
)
|
|
405
456
|
load_expressions(node)
|
|
406
457
|
return node
|
|
@@ -425,6 +476,39 @@ def set_additional_attributes(attribute_names, elm, node):
|
|
|
425
476
|
setattr(node, attributename, attribute)
|
|
426
477
|
|
|
427
478
|
|
|
479
|
+
def get_context_type(node):
|
|
480
|
+
context_type = getattr(node, "context_type", None)
|
|
481
|
+
if context_type:
|
|
482
|
+
return context_type
|
|
483
|
+
if isinstance(node, TriccNodeSelectMultiple):
|
|
484
|
+
return "Question"
|
|
485
|
+
elif isinstance(node, TriccNodeSelectOption):
|
|
486
|
+
if isinstance(node.select, TriccNodeSelectMultiple):
|
|
487
|
+
return "Symptom-Finding"
|
|
488
|
+
else:
|
|
489
|
+
return "Value"
|
|
490
|
+
elif isinstance(node, TriccNodeNote):
|
|
491
|
+
return "InteractSet"
|
|
492
|
+
elif isinstance(
|
|
493
|
+
node,
|
|
494
|
+
(
|
|
495
|
+
TriccNodeDecimal,
|
|
496
|
+
TriccNodeInteger,
|
|
497
|
+
TriccNodeText,
|
|
498
|
+
TriccNodeDate,
|
|
499
|
+
TriccNodeSelectOne,
|
|
500
|
+
TriccNodeSelectYesNo,
|
|
501
|
+
TriccNodeSelectNotAvailable,
|
|
502
|
+
TriccNodeInput,
|
|
503
|
+
),
|
|
504
|
+
):
|
|
505
|
+
return "Symptom-Finding"
|
|
506
|
+
elif isinstance(node, (TriccNodeProposedDiagnosis, TriccNodeDiagnosis)):
|
|
507
|
+
return "Diagnosis"
|
|
508
|
+
elif issubclass(node.__class__, TriccNodeCalculateBase):
|
|
509
|
+
return "Calculation"
|
|
510
|
+
else:
|
|
511
|
+
return "Misc"
|
|
428
512
|
|
|
429
513
|
|
|
430
514
|
def get_select_options(diagram, select_node, nodes):
|
|
@@ -435,16 +519,12 @@ def get_select_options(diagram, select_node, nodes):
|
|
|
435
519
|
for elm in list:
|
|
436
520
|
name = elm.attrib.get("name")
|
|
437
521
|
if name in options_name_list and not name.endswith("_"):
|
|
438
|
-
logger.critical(
|
|
439
|
-
"Select question {0} have twice the option name {1}".format(
|
|
440
|
-
select_node.get_name(), name
|
|
441
|
-
)
|
|
442
|
-
)
|
|
522
|
+
logger.critical("Select question {0} have twice the option name {1}".format(select_node.get_name(), name))
|
|
443
523
|
else:
|
|
444
524
|
options_name_list.append(name)
|
|
445
|
-
|
|
525
|
+
|
|
446
526
|
external_id = elm.attrib.get("id")
|
|
447
|
-
id = get_id(external_id, diagram.attrib.get(
|
|
527
|
+
id = get_id(external_id, diagram.attrib.get("id"))
|
|
448
528
|
option = TriccNodeSelectOption(
|
|
449
529
|
id=id,
|
|
450
530
|
label=elm.attrib.get("label"),
|
|
@@ -453,8 +533,8 @@ def get_select_options(diagram, select_node, nodes):
|
|
|
453
533
|
list_name=select_node.list_name,
|
|
454
534
|
activity=select_node.activity,
|
|
455
535
|
group=select_node.group,
|
|
456
|
-
|
|
457
|
-
set_additional_attributes(["save", "relevance"], elm, option)
|
|
536
|
+
)
|
|
537
|
+
set_additional_attributes(["save", "relevance", "context_type"], elm, option)
|
|
458
538
|
load_expressions(option)
|
|
459
539
|
options[i] = option
|
|
460
540
|
nodes[id] = option
|
|
@@ -464,7 +544,7 @@ def get_select_options(diagram, select_node, nodes):
|
|
|
464
544
|
else:
|
|
465
545
|
return options
|
|
466
546
|
|
|
467
|
-
|
|
547
|
+
# TBR START
|
|
468
548
|
|
|
469
549
|
|
|
470
550
|
def get_max_version(dict):
|
|
@@ -484,11 +564,10 @@ def get_max_named_version(calculates, name):
|
|
|
484
564
|
return max
|
|
485
565
|
|
|
486
566
|
|
|
487
|
-
|
|
488
567
|
def inject_bridge_path(node, nodes):
|
|
489
568
|
calc_name = "p" + node.id
|
|
490
569
|
calc_id = generate_id(calc_name)
|
|
491
|
-
|
|
570
|
+
|
|
492
571
|
data = {
|
|
493
572
|
"id": calc_id,
|
|
494
573
|
"group": node.group,
|
|
@@ -501,22 +580,16 @@ def inject_bridge_path(node, nodes):
|
|
|
501
580
|
nodes[n.source]
|
|
502
581
|
for n in list(
|
|
503
582
|
filter(
|
|
504
|
-
lambda x: (x.target == node.id or x.target == node)
|
|
505
|
-
and x.source in nodes,
|
|
583
|
+
lambda x: (x.target == node.id or x.target == node) and x.source in nodes,
|
|
506
584
|
node.activity.edges,
|
|
507
585
|
)
|
|
508
586
|
)
|
|
509
587
|
]
|
|
510
|
-
if (
|
|
511
|
-
|
|
588
|
+
if (
|
|
589
|
+
len(prev_nodes) > 1
|
|
590
|
+
and sum(
|
|
512
591
|
[
|
|
513
|
-
(
|
|
514
|
-
0
|
|
515
|
-
if issubclass(
|
|
516
|
-
n.__class__, (TriccNodeDisplayCalculateBase, TriccNodeRhombus)
|
|
517
|
-
)
|
|
518
|
-
else 1
|
|
519
|
-
)
|
|
592
|
+
(0 if issubclass(n.__class__, (TriccNodeDisplayCalculateBase, TriccNodeRhombus)) else 1)
|
|
520
593
|
for n in prev_nodes
|
|
521
594
|
]
|
|
522
595
|
)
|
|
@@ -545,7 +618,7 @@ def enrich_node(diagram, media_path, edge, node, activity, help_before=False):
|
|
|
545
618
|
# get node and process type
|
|
546
619
|
type, message = get_message(diagram, edge.source_external_id)
|
|
547
620
|
if type is not None:
|
|
548
|
-
if type ==
|
|
621
|
+
if type == "help":
|
|
549
622
|
help = TriccNodeMoreInfo(
|
|
550
623
|
id=generate_id(),
|
|
551
624
|
name=f"{node.name}.more_info",
|
|
@@ -553,7 +626,7 @@ def enrich_node(diagram, media_path, edge, node, activity, help_before=False):
|
|
|
553
626
|
parent=node,
|
|
554
627
|
required=None,
|
|
555
628
|
)
|
|
556
|
-
#node.help = message
|
|
629
|
+
# node.help = message
|
|
557
630
|
if help_before:
|
|
558
631
|
inject_node_before(help, node, activity)
|
|
559
632
|
else:
|
|
@@ -585,34 +658,41 @@ def enrich_node(diagram, media_path, edge, node, activity, help_before=False):
|
|
|
585
658
|
return None, None
|
|
586
659
|
else:
|
|
587
660
|
logger.warning(f"edge from an unsuported node {edge.source_external_id}")
|
|
588
|
-
|
|
661
|
+
|
|
589
662
|
return None, None
|
|
590
663
|
|
|
591
664
|
|
|
592
|
-
get_style_dict
|
|
665
|
+
def get_style_dict(style):
|
|
666
|
+
return dict(item.split("=", 1) for item in style.split(";") if "=" in item)
|
|
593
667
|
|
|
594
668
|
|
|
595
|
-
def severity_from_color(color):
|
|
596
|
-
if color ==
|
|
597
|
-
return
|
|
598
|
-
elif color ==
|
|
599
|
-
return
|
|
669
|
+
def severity_from_color(color):
|
|
670
|
+
if color == "#fff2cc":
|
|
671
|
+
return "moderate"
|
|
672
|
+
elif color == "#f8cecc":
|
|
673
|
+
return "severe"
|
|
600
674
|
else:
|
|
601
|
-
return
|
|
602
|
-
|
|
675
|
+
return "light"
|
|
603
676
|
|
|
604
677
|
|
|
605
678
|
def add_tricc_base_node(
|
|
606
|
-
diagram,
|
|
679
|
+
diagram,
|
|
680
|
+
nodes,
|
|
681
|
+
type,
|
|
682
|
+
list,
|
|
683
|
+
group,
|
|
684
|
+
attributes=[],
|
|
685
|
+
mandatory_attributes=[],
|
|
686
|
+
has_options=None,
|
|
607
687
|
):
|
|
608
688
|
for elm in list:
|
|
609
689
|
external_id = elm.attrib.get("id")
|
|
610
|
-
id = get_id(
|
|
611
|
-
|
|
690
|
+
id = get_id(external_id, diagram.attrib.get("id"))
|
|
691
|
+
elm.attrib.get("parent")
|
|
612
692
|
node = type(
|
|
613
693
|
external_id=external_id,
|
|
614
694
|
id=id,
|
|
615
|
-
#parent=parent,
|
|
695
|
+
# parent=parent,
|
|
616
696
|
group=group,
|
|
617
697
|
activity=group,
|
|
618
698
|
**set_mandatory_attribute(elm, mandatory_attributes, diagram),
|
|
@@ -630,106 +710,99 @@ def add_tricc_base_node(
|
|
|
630
710
|
node.options = get_select_yes_no_options(node, group)
|
|
631
711
|
nodes[node.options[0].id] = node.options[0]
|
|
632
712
|
nodes[node.options[1].id] = node.options[1]
|
|
633
|
-
elif type == TriccNodeProposedDiagnosis and getattr(node,
|
|
713
|
+
elif type == TriccNodeProposedDiagnosis and getattr(node, "severity", "") is None:
|
|
634
714
|
mxcell = get_mxcell(diagram, external_id)
|
|
635
|
-
styles = get_style_dict(mxcell.attrib.get(
|
|
636
|
-
if
|
|
637
|
-
node.severity = severity_from_color(styles[
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
715
|
+
styles = get_style_dict(mxcell.attrib.get("style", ""))
|
|
716
|
+
if "fillColor" in styles and styles["fillColor"] != "none":
|
|
717
|
+
node.severity = severity_from_color(styles["fillColor"])
|
|
718
|
+
|
|
641
719
|
set_additional_attributes(attributes, elm, node)
|
|
642
720
|
load_expressions(node)
|
|
643
721
|
nodes[id] = node
|
|
644
722
|
|
|
645
723
|
|
|
646
724
|
def load_expressions(node):
|
|
647
|
-
if getattr(node,
|
|
648
|
-
node.constraint = parse_expression(
|
|
649
|
-
if getattr(node,
|
|
650
|
-
node.expression = parse_expression(
|
|
651
|
-
if getattr(node,
|
|
652
|
-
node.relevance = parse_expression(
|
|
653
|
-
if getattr(node,
|
|
654
|
-
node.trigger = parse_expression(
|
|
655
|
-
if getattr(node,
|
|
656
|
-
node.default = parse_expression(
|
|
657
|
-
if getattr(node,
|
|
725
|
+
if getattr(node, "constraint", None):
|
|
726
|
+
node.constraint = parse_expression("", node.constraint)
|
|
727
|
+
if getattr(node, "expression", None):
|
|
728
|
+
node.expression = parse_expression("", node.expression)
|
|
729
|
+
if getattr(node, "relevance", None):
|
|
730
|
+
node.relevance = parse_expression("", node.relevance)
|
|
731
|
+
if getattr(node, "trigger", None):
|
|
732
|
+
node.trigger = parse_expression("", node.trigger)
|
|
733
|
+
if getattr(node, "default", None):
|
|
734
|
+
node.default = parse_expression("", node.default)
|
|
735
|
+
if getattr(node, "reference", None):
|
|
658
736
|
if isinstance(node, TriccNodeRhombus):
|
|
659
737
|
node.label = remove_html(node.label)
|
|
660
738
|
node.expression_reference = parse_expression(node.label, node.reference)
|
|
661
739
|
else:
|
|
662
|
-
node.expression_reference = parse_expression(
|
|
663
|
-
|
|
740
|
+
node.expression_reference = parse_expression("", node.reference)
|
|
741
|
+
|
|
664
742
|
node.reference = node.expression_reference.get_references()
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
743
|
+
|
|
668
744
|
|
|
669
745
|
def parse_expression(label=None, expression=None):
|
|
670
746
|
if expression:
|
|
671
|
-
ref_pattern = r
|
|
672
|
-
|
|
747
|
+
ref_pattern = r"(\$\{[^\}]+\})"
|
|
748
|
+
# only if simple ref
|
|
673
749
|
if not re.search(ref_pattern, expression):
|
|
674
750
|
operation = transform_cql_to_operation(expression, label)
|
|
675
751
|
if isinstance(operation, TriccReference):
|
|
676
752
|
if label:
|
|
677
|
-
if label[0] ==
|
|
753
|
+
if label[0] == "[" and label[-1] == "]":
|
|
678
754
|
operation = TriccOperation(
|
|
679
755
|
operator=TriccOperator.SELECTED,
|
|
680
756
|
reference=[
|
|
681
757
|
operation,
|
|
682
|
-
TriccReference(operation.value + label)
|
|
683
|
-
]
|
|
758
|
+
TriccReference(operation.value + label),
|
|
759
|
+
],
|
|
684
760
|
)
|
|
685
761
|
else:
|
|
686
762
|
for operator in OPERATION_LIST:
|
|
687
763
|
if operator in label:
|
|
688
|
-
if operator ==
|
|
689
|
-
operator =
|
|
764
|
+
if operator == "==":
|
|
765
|
+
operator = "="
|
|
690
766
|
terms = label.split(operator)
|
|
691
767
|
operation = transform_cql_to_operation(
|
|
692
768
|
f"{expression} {operator} {terms[1].replace('?', '').strip()}",
|
|
693
|
-
label
|
|
769
|
+
label,
|
|
694
770
|
)
|
|
695
771
|
break
|
|
696
772
|
# implied is true
|
|
697
773
|
if isinstance(operation, TriccReference):
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
774
|
+
operation = TriccOperation(
|
|
775
|
+
operator=TriccOperator.ISTRUE,
|
|
776
|
+
reference=[
|
|
777
|
+
operation,
|
|
778
|
+
],
|
|
779
|
+
)
|
|
780
|
+
|
|
705
781
|
else:
|
|
706
782
|
pass
|
|
707
783
|
|
|
708
784
|
else:
|
|
709
|
-
operation = transform_cql_to_operation(
|
|
710
|
-
|
|
711
|
-
label
|
|
712
|
-
)
|
|
713
|
-
|
|
785
|
+
operation = transform_cql_to_operation(expression.replace("${", '"').replace("}", '"'), label)
|
|
786
|
+
|
|
714
787
|
if operation is None:
|
|
715
788
|
logger.warning(f"unable to parse: {expression} ")
|
|
716
789
|
return expression
|
|
717
790
|
return operation
|
|
718
|
-
|
|
791
|
+
|
|
719
792
|
|
|
720
793
|
def set_mandatory_attribute(elm, mandatory_attributes, diagram=None):
|
|
721
794
|
param = {}
|
|
722
|
-
diagram_id = diagram.attrib.get(
|
|
795
|
+
diagram_id = diagram.attrib.get("id")
|
|
723
796
|
for attributes in mandatory_attributes:
|
|
724
|
-
if attributes ==
|
|
797
|
+
if attributes == "name":
|
|
725
798
|
name = elm.attrib.get("name")
|
|
726
799
|
id = elm.attrib.get("id")
|
|
727
800
|
attribute_value = _get_name(name, id, diagram_id)
|
|
728
|
-
elif attributes ==
|
|
801
|
+
elif attributes == "list_name":
|
|
729
802
|
name = elm.attrib.get("name")
|
|
730
803
|
id = elm.attrib.get("id")
|
|
731
|
-
attribute_value = TRICC_LIST_NAME.format(clean_str(_get_name(name, id, diagram_id), replace_dots=
|
|
732
|
-
else:
|
|
804
|
+
attribute_value = TRICC_LIST_NAME.format(clean_str(_get_name(name, id, diagram_id), replace_dots=True))
|
|
805
|
+
else:
|
|
733
806
|
attribute_value = elm.attrib.get(attributes)
|
|
734
807
|
if attribute_value is None:
|
|
735
808
|
if elm.attrib.get("label") is not None:
|
|
@@ -738,21 +811,19 @@ def set_mandatory_attribute(elm, mandatory_attributes, diagram=None):
|
|
|
738
811
|
display_name = elm.attrib.get("name")
|
|
739
812
|
else:
|
|
740
813
|
display_name = elm.attrib.get("id")
|
|
741
|
-
|
|
814
|
+
|
|
742
815
|
if attributes == "source":
|
|
743
816
|
if elm.attrib.get("target") is not None:
|
|
744
|
-
logger.critical(
|
|
745
|
-
"the attibute target is {}".format(elm.attrib.get("target"))
|
|
746
|
-
)
|
|
817
|
+
logger.critical("the attibute target is {}".format(elm.attrib.get("target")))
|
|
747
818
|
elif attributes == "target":
|
|
748
819
|
if elm.attrib.get("source") is not None:
|
|
749
|
-
logger.critical(
|
|
750
|
-
|
|
751
|
-
)
|
|
752
|
-
|
|
820
|
+
logger.critical("the attibute target is {}".format(elm.attrib.get("source")))
|
|
821
|
+
|
|
753
822
|
logger.critical(
|
|
754
823
|
"the attibute {} is mandatory but not found in {} within group {}".format(
|
|
755
|
-
attributes,
|
|
824
|
+
attributes,
|
|
825
|
+
display_name,
|
|
826
|
+
diagram.attrib.get("name") if diagram is not None else "",
|
|
756
827
|
)
|
|
757
828
|
)
|
|
758
829
|
exit(1)
|
|
@@ -792,12 +863,10 @@ def add_group(elm, diagram, nodes, groups, parent_group, activity):
|
|
|
792
863
|
id=id,
|
|
793
864
|
external_id=external_id,
|
|
794
865
|
group=parent_group,
|
|
795
|
-
activity=activity
|
|
866
|
+
activity=activity,
|
|
796
867
|
)
|
|
797
868
|
# get elememt witn parent = id and tricc_type defiend
|
|
798
|
-
list_child = get_tricc_type_list(
|
|
799
|
-
diagram, ["object", "UserObject"], tricc_type=None, parent_id=id
|
|
800
|
-
)
|
|
869
|
+
list_child = get_tricc_type_list(diagram, ["object", "UserObject"], tricc_type=None, parent_id=id)
|
|
801
870
|
add_group_to_child(group, diagram, list_child, nodes, groups, parent_group)
|
|
802
871
|
if group is not None:
|
|
803
872
|
groups[group.id] = group
|
|
@@ -813,12 +882,10 @@ def add_group_to_child(group, diagram, list_child, nodes, groups, parent_group):
|
|
|
813
882
|
tricc_type=None,
|
|
814
883
|
parent_id=child_elm.attrib.get("id"),
|
|
815
884
|
)
|
|
816
|
-
add_group_to_child(
|
|
817
|
-
group, diagram, list_sub_child, nodes, groups, parent_group
|
|
818
|
-
)
|
|
885
|
+
add_group_to_child(group, diagram, list_sub_child, nodes, groups, parent_group)
|
|
819
886
|
elif child_elm.attrib.get("tricc_type") == TriccNodeType.page:
|
|
820
887
|
child_group_id = child_elm.attrib.get("id")
|
|
821
|
-
if not
|
|
888
|
+
if child_group_id not in groups:
|
|
822
889
|
child_group = add_group(child_elm, diagram, nodes, groups, group)
|
|
823
890
|
else:
|
|
824
891
|
child_group = groups[child_group_id]
|
|
@@ -843,16 +910,14 @@ def add_image_from_style(style, path):
|
|
|
843
910
|
image_attrib = None
|
|
844
911
|
if style is not None and "image=data:image/" in style:
|
|
845
912
|
image_attrib = style.split("image=data:image/")
|
|
846
|
-
if image_attrib is not None and len(image_attrib)== 2:
|
|
913
|
+
if image_attrib is not None and len(image_attrib) == 2:
|
|
847
914
|
image_parts = image_attrib[1].split(",")
|
|
848
915
|
if len(image_parts) == 2:
|
|
849
916
|
payload = image_parts[1][:-1]
|
|
850
|
-
image_name = hashlib.md5(payload.encode(
|
|
917
|
+
image_name = hashlib.md5(payload.encode("utf-8")).hexdigest()
|
|
851
918
|
path = os.path.join(path, "images")
|
|
852
919
|
file_name = os.path.join(path, image_name + "." + image_parts[0])
|
|
853
|
-
if not (
|
|
854
|
-
os.path.isdir(path)
|
|
855
|
-
): # check if it exists, because if it does, error will be raised
|
|
920
|
+
if not (os.path.isdir(path)): # check if it exists, because if it does, error will be raised
|
|
856
921
|
# (later change to make folder complaint to CHT)
|
|
857
922
|
os.makedirs(path, exist_ok=True)
|
|
858
923
|
with open(file_name, "wb") as fh:
|
|
@@ -862,13 +927,6 @@ def add_image_from_style(style, path):
|
|
|
862
927
|
return None, None
|
|
863
928
|
|
|
864
929
|
|
|
865
|
-
def get_contained_main_node(diagram, id):
|
|
866
|
-
list = get_mxcell_parent_list(diagram, id, media_nodes)
|
|
867
|
-
if isinstance(list, List) and len(list) > 0:
|
|
868
|
-
# use only the first one
|
|
869
|
-
return list[0]
|
|
870
|
-
|
|
871
|
-
|
|
872
930
|
def get_message(diagram, id):
|
|
873
931
|
elm = get_elm(diagram, id)
|
|
874
932
|
if elm is not None:
|
|
@@ -889,14 +947,12 @@ def get_edges(diagram):
|
|
|
889
947
|
id = get_id(external_id, diagram.attrib.get("id"))
|
|
890
948
|
edge = TriccEdge(
|
|
891
949
|
id=id,
|
|
892
|
-
**set_mandatory_attribute(
|
|
893
|
-
elm, ["source", "parent", "target"], diagram
|
|
894
|
-
),
|
|
950
|
+
**set_mandatory_attribute(elm, ["source", "parent", "target"], diagram),
|
|
895
951
|
)
|
|
896
952
|
edge.source_external_id = edge.source
|
|
897
953
|
edge.target_external_id = edge.target
|
|
898
|
-
edge.source = get_id(edge.source,
|
|
899
|
-
edge.target = get_id(edge.target,
|
|
954
|
+
edge.source = get_id(edge.source, diagram.attrib.get("id"))
|
|
955
|
+
edge.target = get_id(edge.target, diagram.attrib.get("id"))
|
|
900
956
|
set_additional_attributes(["value"], elm, edge)
|
|
901
957
|
if edge.value is not None:
|
|
902
958
|
edge.value = remove_html(edge.value)
|
|
@@ -904,7 +960,7 @@ def get_edges(diagram):
|
|
|
904
960
|
return edges
|
|
905
961
|
|
|
906
962
|
|
|
907
|
-
|
|
963
|
+
# Process edges
|
|
908
964
|
|
|
909
965
|
|
|
910
966
|
def process_factor_edge(edge, nodes):
|
|
@@ -913,7 +969,10 @@ def process_factor_edge(edge, nodes):
|
|
|
913
969
|
source = nodes[edge.source]
|
|
914
970
|
return TriccNodeCalculate(
|
|
915
971
|
id=edge.id,
|
|
916
|
-
expression_reference=TriccOperation(
|
|
972
|
+
expression_reference=TriccOperation(
|
|
973
|
+
TriccOperator.MULTIPLIED,
|
|
974
|
+
[TriccReference(nodes[edge.source].name), TriccStatic(float(factor))],
|
|
975
|
+
),
|
|
917
976
|
reference=[TriccReference(source.name)],
|
|
918
977
|
activity=source.activity,
|
|
919
978
|
group=source.group,
|
|
@@ -922,15 +981,20 @@ def process_factor_edge(edge, nodes):
|
|
|
922
981
|
return None
|
|
923
982
|
|
|
924
983
|
|
|
925
|
-
def process_condition_edge(edge, nodes):
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
operation = parse_expression('', expression=label.replace('$this', node_ref ))
|
|
984
|
+
def process_condition_edge(edge, label, nodes):
|
|
985
|
+
source = nodes[edge.source]
|
|
986
|
+
node_ref = f'"{source.name}"'
|
|
987
|
+
if "$this" in label:
|
|
988
|
+
operation = parse_expression("", expression=label.replace("$this", node_ref))
|
|
931
989
|
else:
|
|
932
990
|
operation = parse_expression(label, expression=node_ref)
|
|
991
|
+
|
|
933
992
|
if operation and isinstance(operation, TriccOperation):
|
|
993
|
+
# special management for simple operation
|
|
994
|
+
if issubclass(source.__class__, TriccNodeSelect) and "$this" not in label:
|
|
995
|
+
operation.replace_node(
|
|
996
|
+
TriccReference(source.name),
|
|
997
|
+
get_count_terms_details(source, None, False))
|
|
934
998
|
# insert rhombus
|
|
935
999
|
return TriccNodeRhombus(
|
|
936
1000
|
id=edge.id,
|
|
@@ -939,13 +1003,10 @@ def process_condition_edge(edge, nodes):
|
|
|
939
1003
|
path=nodes[edge.source],
|
|
940
1004
|
activity=nodes[edge.source].activity,
|
|
941
1005
|
group=nodes[edge.source].group,
|
|
942
|
-
label=label
|
|
1006
|
+
label=label,
|
|
943
1007
|
)
|
|
944
1008
|
|
|
945
1009
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
1010
|
def process_exclusive_edge(edge, nodes):
|
|
950
1011
|
error = None
|
|
951
1012
|
if issubclass(nodes[edge.source].__class__, TriccNodeCalculateBase):
|
|
@@ -976,9 +1037,7 @@ def process_exclusive_edge(edge, nodes):
|
|
|
976
1037
|
|
|
977
1038
|
def process_yesno_edge(edge, nodes):
|
|
978
1039
|
if not edge.value:
|
|
979
|
-
logger.critical(
|
|
980
|
-
"yesNo {} node with labelless edges".format(nodes[edge.source].get_name())
|
|
981
|
-
)
|
|
1040
|
+
logger.critical("yesNo {} node with labelless edges".format(nodes[edge.source].get_name()))
|
|
982
1041
|
exit(1)
|
|
983
1042
|
label = edge.value.strip().lower()
|
|
984
1043
|
yes_option = None
|
|
@@ -997,8 +1056,4 @@ def process_yesno_edge(edge, nodes):
|
|
|
997
1056
|
edge.source = no_option.id
|
|
998
1057
|
edge.source_external_id = None
|
|
999
1058
|
else:
|
|
1000
|
-
logger.warning(
|
|
1001
|
-
"edge {0} is coming from select {1}".format(
|
|
1002
|
-
edge.id, nodes[edge.source].get_name()
|
|
1003
|
-
)
|
|
1004
|
-
)
|
|
1059
|
+
logger.warning("edge {0} is coming from select {1}".format(edge.id, nodes[edge.source].get_name()))
|