tricc-oo 1.5.22__py3-none-any.whl → 1.5.23__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 +13 -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 +39 -53
- 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 +144 -88
- 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 +57 -69
- tricc_oo/strategies/output/base_output_strategy.py +108 -67
- tricc_oo/strategies/output/spice.py +106 -127
- tricc_oo/strategies/output/xls_form.py +275 -200
- tricc_oo/strategies/output/xlsform_cdss.py +623 -142
- tricc_oo/strategies/output/xlsform_cht.py +106 -114
- tricc_oo/strategies/output/xlsform_cht_hf.py +13 -24
- tricc_oo/visitors/tricc.py +1191 -1021
- 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.23.dist-info}/METADATA +3 -1
- tricc_oo-1.5.23.dist-info/RECORD +47 -0
- tricc_oo-1.5.23.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.23.dist-info}/WHEEL +0 -0
- {tricc_oo-1.5.22.dist-info → tricc_oo-1.5.23.dist-info}/top_level.txt +0 -0
tricc_oo/visitors/tricc.py
CHANGED
|
@@ -1,65 +1,118 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import logging
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import requests
|
|
4
|
+
import base64
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from tricc_oo.converters.utils import generate_id
|
|
8
|
+
from tricc_oo.models.base import (
|
|
9
|
+
TriccBaseModel,
|
|
10
|
+
TriccOperator, TriccOperation, TriccStatic, TriccReference, not_clean,
|
|
11
|
+
and_join, or_join, clean_or_list, nand_join, TriccEdge
|
|
12
|
+
)
|
|
13
|
+
from tricc_oo.models.ordered_set import OrderedSet
|
|
14
|
+
from tricc_oo.models.calculate import (
|
|
15
|
+
TriccNodeDisplayBridge,
|
|
16
|
+
TriccNodeBridge,
|
|
17
|
+
TriccNodeWait,
|
|
18
|
+
TriccNodeCalculate,
|
|
19
|
+
TriccNodeRhombus,
|
|
20
|
+
TriccNodeDisplayCalculateBase,
|
|
21
|
+
TriccNodeExclusive,
|
|
22
|
+
TriccNodeProposedDiagnosis,
|
|
23
|
+
TriccNodeCount,
|
|
24
|
+
TriccNodeAdd,
|
|
25
|
+
TriccNodeFakeCalculateBase,
|
|
26
|
+
TriccRhombusMixIn,
|
|
27
|
+
TriccNodeInput,
|
|
28
|
+
TriccNodeActivityEnd,
|
|
29
|
+
TriccNodeActivityStart,
|
|
30
|
+
TriccNodeEnd,
|
|
31
|
+
get_node_from_id,
|
|
32
|
+
|
|
33
|
+
)
|
|
34
|
+
from tricc_oo.models.tricc import (
|
|
35
|
+
TriccNodeCalculateBase, TriccNodeActivity, TriccNodeBaseModel, TriccNodeNumber,
|
|
36
|
+
TriccNodeSelectMultiple,
|
|
37
|
+
TriccNodeSelectOption,
|
|
38
|
+
TriccNodeSelectYesNo,
|
|
39
|
+
TriccNodeInputModel,
|
|
40
|
+
TriccNodeSelect,
|
|
41
|
+
TriccNodeSelectNotAvailable,
|
|
42
|
+
TriccNodeMoreInfo,
|
|
43
|
+
TriccNodeDisplayModel,
|
|
44
|
+
TriccNodeMainStart,
|
|
45
|
+
TriccNodeAcceptDiagnostic,
|
|
46
|
+
)
|
|
7
47
|
from tricc_oo.visitors.utils import PROCESSES
|
|
48
|
+
from tricc_oo.converters.cql_to_operation import transform_cql_to_operation
|
|
8
49
|
from tricc_oo.converters.datadictionnary import lookup_codesystems_code
|
|
50
|
+
from tricc_oo.converters.tricc_to_xls_form import get_list_names, get_export_name
|
|
9
51
|
|
|
10
52
|
logger = logging.getLogger("default")
|
|
11
53
|
ONE_QUESTION_AT_A_TIME = False
|
|
12
54
|
|
|
13
|
-
TRICC_TRUE_VALUE =
|
|
14
|
-
TRICC_FALSE_VALUE =
|
|
55
|
+
TRICC_TRUE_VALUE = "true"
|
|
56
|
+
TRICC_FALSE_VALUE = "false"
|
|
57
|
+
|
|
15
58
|
|
|
16
|
-
def merge_node(from_node,to_node):
|
|
59
|
+
def merge_node(from_node, to_node):
|
|
17
60
|
if from_node.activity != to_node.activity:
|
|
18
61
|
logger.critical("Cannot merge nodes from different activities")
|
|
19
|
-
elif issubclass(from_node.__class__, TriccNodeCalculateBase) and issubclass(
|
|
62
|
+
elif issubclass(from_node.__class__, TriccNodeCalculateBase) and issubclass(
|
|
63
|
+
to_node.__class__, TriccNodeCalculateBase
|
|
64
|
+
):
|
|
20
65
|
for e in to_node.activity.edges:
|
|
21
66
|
if e.target == from_node.id:
|
|
22
67
|
e.target = to_node.id
|
|
23
68
|
else:
|
|
24
69
|
logger.critical("Cannot merge not calculate nodes ")
|
|
25
|
-
|
|
70
|
+
|
|
26
71
|
|
|
27
72
|
def get_max_version(dict):
|
|
28
73
|
max_version = None
|
|
29
74
|
for id, sim_node in dict.items():
|
|
30
|
-
if max_version is None or
|
|
75
|
+
if max_version is None or max_version.version < sim_node.version:
|
|
31
76
|
max_version = sim_node
|
|
32
77
|
return max_version
|
|
33
78
|
|
|
79
|
+
|
|
34
80
|
def get_versions(name, iterable):
|
|
35
81
|
return [n for n in iterable if version_filter(name)(n)]
|
|
36
82
|
|
|
83
|
+
|
|
37
84
|
def version_filter(name):
|
|
38
|
-
return
|
|
85
|
+
return (
|
|
86
|
+
lambda item: hasattr(item, "name")
|
|
87
|
+
and ((isinstance(item, TriccNodeEnd) and name == item.get_reference()) or item.name == name)
|
|
88
|
+
and not isinstance(item, TriccNodeSelectOption)
|
|
89
|
+
)
|
|
90
|
+
|
|
39
91
|
|
|
40
|
-
def get_last_version(name, processed_nodes,
|
|
92
|
+
def get_last_version(name, processed_nodes, _list=None):
|
|
41
93
|
max_version = None
|
|
42
94
|
if isinstance(_list, dict):
|
|
43
95
|
_list = _list[name].values() if name in _list else []
|
|
44
96
|
if _list is None:
|
|
45
97
|
if isinstance(processed_nodes, OrderedSet):
|
|
46
98
|
return processed_nodes.find_last(version_filter(name))
|
|
47
|
-
else:
|
|
99
|
+
else:
|
|
48
100
|
_list = get_versions(name, processed_nodes)
|
|
49
101
|
if _list:
|
|
50
|
-
for
|
|
102
|
+
for sim_node in _list:
|
|
51
103
|
# get the max version while not taking a node that have a next node before next calc
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
or
|
|
104
|
+
if (
|
|
105
|
+
max_version is None
|
|
106
|
+
or max_version.activity.path_len < sim_node.activity.path_len
|
|
107
|
+
or max_version.path_len < sim_node.path_len
|
|
55
108
|
or (max_version.path_len == sim_node.path_len and hash(max_version.id) < hash(sim_node.id))
|
|
56
|
-
|
|
109
|
+
):
|
|
57
110
|
max_version = sim_node
|
|
58
111
|
if not max_version:
|
|
59
|
-
already_processed = list(filter(lambda p_node: hasattr(p_node,
|
|
112
|
+
already_processed = list(filter(lambda p_node: hasattr(p_node, "name") and p_node.name == name, _list))
|
|
60
113
|
if already_processed:
|
|
61
|
-
max_version = sorted(
|
|
62
|
-
|
|
114
|
+
max_version = sorted(already_processed, key=lambda x: x.path_len, reverse=False)[0]
|
|
115
|
+
|
|
63
116
|
return max_version
|
|
64
117
|
|
|
65
118
|
|
|
@@ -67,324 +120,321 @@ def get_last_version(name, processed_nodes, _list=None):
|
|
|
67
120
|
# node is the node to calculate
|
|
68
121
|
# processed_nodes are the list of processed nodes
|
|
69
122
|
def get_node_expressions(node, processed_nodes, process=None):
|
|
70
|
-
get_overall_exp = issubclass(node.__class__, TriccNodeCalculateBase) and not issubclass(
|
|
123
|
+
get_overall_exp = issubclass(node.__class__, TriccNodeCalculateBase) and not issubclass(
|
|
124
|
+
node.__class__, (TriccNodeDisplayBridge, TriccNodeBridge)
|
|
125
|
+
)
|
|
71
126
|
expression = None
|
|
72
127
|
# in case of recursive call processed_nodes will be None
|
|
73
128
|
if processed_nodes is None or is_ready_to_process(node, processed_nodes=processed_nodes):
|
|
74
|
-
expression = get_node_expression(
|
|
75
|
-
|
|
129
|
+
expression = get_node_expression(
|
|
130
|
+
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, process=process
|
|
131
|
+
)
|
|
132
|
+
|
|
76
133
|
# if get_overall_exp:
|
|
77
|
-
# if expression and (not isinstance(expression, str) or expression != '')
|
|
134
|
+
# if expression and (not isinstance(expression, str) or expression != '')
|
|
135
|
+
# and expression is not TriccStatic(True) :
|
|
78
136
|
# num_expression = TriccOperation(
|
|
79
137
|
# TriccOperator.CAST_NUMBER,
|
|
80
138
|
# [expression]
|
|
81
139
|
# )
|
|
82
140
|
# elif expression is TriccStatic(True) or (not expression and get_overall_exp):
|
|
83
|
-
# expression = TriccStatic(True)
|
|
141
|
+
# expression = TriccStatic(True)
|
|
84
142
|
# else:
|
|
85
143
|
# expression = None
|
|
86
144
|
if (
|
|
87
|
-
issubclass(node.__class__, TriccNodeCalculateBase)
|
|
88
|
-
and not isinstance(expression, (TriccStatic, TriccReference, TriccOperation))
|
|
89
|
-
and str(expression) !=
|
|
145
|
+
issubclass(node.__class__, TriccNodeCalculateBase)
|
|
146
|
+
and not isinstance(expression, (TriccStatic, TriccReference, TriccOperation))
|
|
147
|
+
and str(expression) != ""
|
|
90
148
|
and not isinstance(node, (TriccNodeWait, TriccNodeActivityEnd, TriccNodeActivityStart, TriccNodeEnd))
|
|
91
149
|
):
|
|
92
150
|
logger.warning("Calculate {0} returning no calculations".format(node.get_name()))
|
|
93
151
|
expression = TriccStatic(True)
|
|
94
152
|
return expression
|
|
95
153
|
|
|
154
|
+
|
|
96
155
|
def set_last_version_false(node, processed_nodes):
|
|
97
|
-
if isinstance(node, (
|
|
156
|
+
if isinstance(node, (TriccNodeSelectOption)):
|
|
98
157
|
return
|
|
99
158
|
node_name = node.name if not isinstance(node, TriccNodeEnd) else node.get_reference()
|
|
100
|
-
#last_version = get_last_version(node_name, processed_nodes) if issubclass(node.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase, TriccNodeEnd)) and not isinstance(node, TriccNodeSelectOption) else None
|
|
101
159
|
last_version = processed_nodes.find_prev(node, version_filter(node_name))
|
|
102
|
-
if last_version and getattr(node,
|
|
103
|
-
# 0-100 for manually specified instance. 100-200 for auto instance
|
|
160
|
+
if last_version and getattr(node, "process", "") != "pause":
|
|
161
|
+
# 0-100 for manually specified instance. 100-200 for auto instance
|
|
104
162
|
node.version = get_next_version(node.name, processed_nodes, last_version.version, 0)
|
|
105
163
|
last_version.last = False
|
|
106
164
|
node.path_len = max(node.path_len, last_version.path_len + 1)
|
|
107
165
|
return last_version
|
|
108
|
-
|
|
166
|
+
|
|
167
|
+
|
|
109
168
|
def get_version_inheritance(node, last_version, processed_nodes):
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
'$this',
|
|
150
|
-
last_version
|
|
151
|
-
]
|
|
152
|
-
)
|
|
153
|
-
|
|
169
|
+
# FIXME this is for XLS form where only calculate are evaluated
|
|
170
|
+
# for a activity that is not triggered
|
|
171
|
+
if not issubclass(node.__class__, (TriccNodeInputModel)):
|
|
172
|
+
node.last = True
|
|
173
|
+
if issubclass(node.__class__, (TriccNodeDisplayCalculateBase, TriccNodeEnd)) and node.name is not None:
|
|
174
|
+
# logger.debug("set last to false for node {}
|
|
175
|
+
# and add its link it to next one".format(last_used_calc.get_name()))
|
|
176
|
+
if node.prev_nodes:
|
|
177
|
+
set_prev_next_node(last_version, node)
|
|
178
|
+
else:
|
|
179
|
+
expression = node.expression or node.expression_reference or getattr(node, "relevance", None)
|
|
180
|
+
expression = merge_expression(expression, last_version)
|
|
181
|
+
if node.expression:
|
|
182
|
+
node.expression = expression
|
|
183
|
+
elif node.expression_reference:
|
|
184
|
+
node.expression_reference = expression
|
|
185
|
+
elif node.relevance:
|
|
186
|
+
node.relevance = expression
|
|
187
|
+
else:
|
|
188
|
+
node.last = False
|
|
189
|
+
calc = TriccNodeCalculate(
|
|
190
|
+
id=generate_id(f"save{node.id}"),
|
|
191
|
+
name=node.name,
|
|
192
|
+
path_len=node.path_len + 1,
|
|
193
|
+
# version=get_next_version(node.name, processed_nodes, node.version+2),
|
|
194
|
+
expression=merge_expression(node, last_version),
|
|
195
|
+
label=f"merge{node.id}",
|
|
196
|
+
last=True,
|
|
197
|
+
activity=node.activity,
|
|
198
|
+
group=node.group,
|
|
199
|
+
)
|
|
200
|
+
node.activity.nodes[calc.id] = calc
|
|
201
|
+
node.activity.calculates.append(calc)
|
|
202
|
+
# set_last_version_false(calc, processed_nodes)
|
|
203
|
+
processed_nodes.add(calc)
|
|
204
|
+
if issubclass(node.__class__, TriccNodeInputModel):
|
|
205
|
+
node.expression = TriccOperation(TriccOperator.COALESCE, ["$this", last_version])
|
|
206
|
+
|
|
207
|
+
|
|
154
208
|
def merge_expression(expression, last_version):
|
|
155
209
|
datatype = expression.get_datatype()
|
|
156
|
-
if datatype ==
|
|
157
|
-
expression = or_join(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
elif datatype == 'number':
|
|
162
|
-
expression = TriccOperation(
|
|
163
|
-
TriccOperator.PLUS,
|
|
164
|
-
[last_version, expression]
|
|
165
|
-
)
|
|
210
|
+
if datatype == "boolean":
|
|
211
|
+
expression = or_join([TriccOperation(TriccOperator.ISTRUE, [last_version]), expression])
|
|
212
|
+
|
|
213
|
+
elif datatype == "number":
|
|
214
|
+
expression = TriccOperation(TriccOperator.PLUS, [last_version, expression])
|
|
166
215
|
else:
|
|
167
|
-
expression = TriccOperation(
|
|
168
|
-
TriccOperator.COALESCE,
|
|
169
|
-
[last_version, expression]
|
|
170
|
-
)
|
|
216
|
+
expression = TriccOperation(TriccOperator.COALESCE, [last_version, expression])
|
|
171
217
|
return expression
|
|
172
218
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
219
|
+
|
|
220
|
+
def process_calculate(
|
|
221
|
+
node, processed_nodes, stashed_nodes, calculates, used_calculates, warn=False, process=None, **kwargs
|
|
222
|
+
):
|
|
223
|
+
# used_calculates dict[name, Dict[id, node]]
|
|
224
|
+
# processed_nodes Dict[id, node]
|
|
225
|
+
# calculates dict[name, Dict[id, node]]
|
|
226
|
+
|
|
180
227
|
if node not in processed_nodes:
|
|
181
228
|
# generate condition
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
warn = warn,
|
|
191
|
-
codesystems= kwargs.get('codesystems', None)
|
|
192
|
-
)
|
|
229
|
+
if is_ready_to_process(node, processed_nodes, True) and process_reference(
|
|
230
|
+
node,
|
|
231
|
+
processed_nodes=processed_nodes,
|
|
232
|
+
calculates=calculates,
|
|
233
|
+
used_calculates=used_calculates,
|
|
234
|
+
replace_reference=False,
|
|
235
|
+
warn=warn,
|
|
236
|
+
codesystems=kwargs.get("codesystems", None),
|
|
193
237
|
):
|
|
194
|
-
if kwargs.get(
|
|
195
|
-
logger.debug(
|
|
238
|
+
if kwargs.get("warn", True):
|
|
239
|
+
logger.debug("Processing relevance for node {0}".format(node.get_name()))
|
|
196
240
|
# tricc diagnostic have the same name as proposed diag but will be serialised with different names
|
|
197
241
|
|
|
198
|
-
last_version =
|
|
242
|
+
last_version = set_last_version_false(node, processed_nodes)
|
|
199
243
|
if last_version:
|
|
200
244
|
last_version = get_version_inheritance(node, last_version, processed_nodes)
|
|
201
245
|
|
|
202
|
-
generate_calculates(node,calculates, used_calculates,processed_nodes=processed_nodes, process=process)
|
|
203
|
-
|
|
204
|
-
|
|
246
|
+
generate_calculates(node, calculates, used_calculates, processed_nodes=processed_nodes, process=process)
|
|
205
247
|
|
|
206
|
-
|
|
207
|
-
if hasattr(node,
|
|
248
|
+
# if has prev, create condition
|
|
249
|
+
if hasattr(node, "relevance") and (node.relevance is None or isinstance(node.relevance, TriccOperation)):
|
|
208
250
|
node.relevance = get_node_expressions(node, processed_nodes=processed_nodes, process=process)
|
|
209
251
|
# manage not Available
|
|
210
252
|
if isinstance(node, TriccNodeSelectNotAvailable):
|
|
211
253
|
# update the checkbox
|
|
212
|
-
if node.parent:
|
|
254
|
+
if node.parent:
|
|
213
255
|
if len(node.prev_nodes) == 1:
|
|
214
256
|
prev = list(node.prev_nodes)[0]
|
|
215
257
|
if isinstance(prev, TriccNodeMoreInfo) and prev.parent.name == node.name:
|
|
216
258
|
prev.parent = node
|
|
217
|
-
|
|
218
|
-
|
|
259
|
+
|
|
219
260
|
# managing more info on NotAvaialbee
|
|
220
261
|
parent_empty = TriccOperation(TriccOperator.ISNULL, [node.parent])
|
|
221
|
-
node.relevance
|
|
262
|
+
node.relevance = and_join([node.parent.relevance, parent_empty])
|
|
222
263
|
node.required = parent_empty
|
|
223
264
|
node.constraint = parent_empty
|
|
224
265
|
node.constraint_message = "Cannot be selected with a value entered above"
|
|
225
266
|
# update the check box parent : create loop error
|
|
226
267
|
node.parent.required = None # "${{{0}}}=''".format(node.name)
|
|
227
268
|
else:
|
|
228
|
-
logger.warning("not available node {} does't have a single parent".format(node.get_name()))
|
|
269
|
+
logger.warning("not available node {} does't have a single parent".format(node.get_name()))
|
|
229
270
|
elif isinstance(node.relevance, TriccOperation):
|
|
230
271
|
relevance_reference = list(node.relevance.get_references())
|
|
231
272
|
for r in relevance_reference:
|
|
232
|
-
if issubclass(r.__class__, (TriccNodeDisplayCalculateBase
|
|
273
|
+
if issubclass(r.__class__, (TriccNodeDisplayCalculateBase)):
|
|
233
274
|
add_used_calculate(node, r, calculates, used_calculates, processed_nodes)
|
|
234
|
-
|
|
235
|
-
if last_version and hasattr(node,
|
|
275
|
+
|
|
276
|
+
if last_version and hasattr(node, "relevance"):
|
|
236
277
|
if isinstance(node, TriccNodeInputModel):
|
|
237
|
-
version_relevance =
|
|
238
|
-
TriccOperator.ISNULL,
|
|
239
|
-
[last_version]
|
|
240
|
-
)
|
|
278
|
+
version_relevance = TriccOperation(TriccOperator.ISNULL, [last_version])
|
|
241
279
|
elif last_version.relevance:
|
|
242
|
-
|
|
243
|
-
last_version.relevance
|
|
244
|
-
)
|
|
280
|
+
version_relevance = not_clean(last_version.relevance)
|
|
245
281
|
elif last_version.activity.relevance:
|
|
246
282
|
version_relevance = not_clean(
|
|
247
|
-
|
|
283
|
+
last_version.activity.relevance,
|
|
248
284
|
)
|
|
249
285
|
else:
|
|
250
286
|
version_relevance = None
|
|
251
|
-
|
|
287
|
+
|
|
252
288
|
if version_relevance:
|
|
253
|
-
if getattr(node,
|
|
254
|
-
node.relevance = and_join(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
node.relevance
|
|
258
|
-
])
|
|
259
|
-
|
|
260
|
-
elif hasattr(node, 'relevance'):
|
|
289
|
+
if getattr(node, "relevance", None):
|
|
290
|
+
node.relevance = and_join([version_relevance, node.relevance])
|
|
291
|
+
|
|
292
|
+
elif hasattr(node, "relevance"):
|
|
261
293
|
node.relevance = version_relevance
|
|
262
294
|
|
|
263
|
-
#if hasattr(node, 'next_nodes'):
|
|
264
|
-
|
|
295
|
+
# if hasattr(node, 'next_nodes'):
|
|
296
|
+
# node.next_nodes=reorder_node_list(node.next_nodes, node.group)
|
|
265
297
|
process_reference(
|
|
266
|
-
node,
|
|
267
|
-
processed_nodes=processed_nodes,
|
|
298
|
+
node,
|
|
299
|
+
processed_nodes=processed_nodes,
|
|
268
300
|
calculates=calculates,
|
|
269
|
-
used_calculates=used_calculates,
|
|
270
|
-
replace_reference=True,
|
|
271
|
-
warn
|
|
272
|
-
codesystems=
|
|
301
|
+
used_calculates=used_calculates,
|
|
302
|
+
replace_reference=True,
|
|
303
|
+
warn=warn,
|
|
304
|
+
codesystems=kwargs.get("codesystems", None),
|
|
273
305
|
)
|
|
274
306
|
if isinstance(node, (TriccNodeMainStart, TriccNodeActivityStart)):
|
|
275
307
|
process_reference(
|
|
276
308
|
node.activity,
|
|
277
|
-
processed_nodes=processed_nodes,
|
|
309
|
+
processed_nodes=processed_nodes,
|
|
278
310
|
calculates=calculates,
|
|
279
|
-
used_calculates=used_calculates,
|
|
280
|
-
replace_reference=True,
|
|
281
|
-
warn
|
|
282
|
-
codesystems=
|
|
311
|
+
used_calculates=used_calculates,
|
|
312
|
+
replace_reference=True,
|
|
313
|
+
warn=warn,
|
|
314
|
+
codesystems=kwargs.get("codesystems", None),
|
|
283
315
|
)
|
|
284
316
|
|
|
285
317
|
return True
|
|
286
318
|
# not ready to process or already processed
|
|
287
319
|
|
|
288
320
|
return False
|
|
289
|
-
|
|
290
321
|
|
|
291
322
|
|
|
292
|
-
def get_max_named_version(calculates,name):
|
|
323
|
+
def get_max_named_version(calculates, name):
|
|
293
324
|
max = 0
|
|
294
|
-
if name
|
|
295
|
-
for
|
|
325
|
+
if name in calculates:
|
|
326
|
+
for node in calculates[name].values():
|
|
296
327
|
if node.version > max:
|
|
297
328
|
max = node.version
|
|
298
329
|
return max
|
|
299
330
|
|
|
331
|
+
|
|
300
332
|
def get_count_node(node):
|
|
301
333
|
count_id = generate_id(f"count{node.id}")
|
|
302
|
-
count_name = "cnt_"+count_id
|
|
334
|
+
count_name = "cnt_" + count_id
|
|
303
335
|
return TriccNodeCount(
|
|
304
|
-
id
|
|
305
|
-
group
|
|
306
|
-
activity
|
|
307
|
-
label
|
|
308
|
-
name
|
|
309
|
-
path_len=node.path_len
|
|
336
|
+
id=count_id,
|
|
337
|
+
group=node.group,
|
|
338
|
+
activity=node.activity,
|
|
339
|
+
label="count: " + node.get_name(),
|
|
340
|
+
name=count_name,
|
|
341
|
+
path_len=node.path_len,
|
|
310
342
|
)
|
|
311
|
-
|
|
312
|
-
### Function that inject a wait after path that will wait for the nodes
|
|
313
|
-
def get_activity_wait(prev_nodes, nodes_to_wait, next_nodes, replaced_node = None, edge_only = False, activity = None):
|
|
314
343
|
|
|
315
|
-
|
|
344
|
+
|
|
345
|
+
# Function that inject a wait after path that will wait for the nodes
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def get_activity_wait(prev_nodes, nodes_to_wait, next_nodes, replaced_node=None, edge_only=False, activity=None):
|
|
349
|
+
|
|
350
|
+
if issubclass(nodes_to_wait.__class__, TriccBaseModel):
|
|
316
351
|
nodes_to_wait = [nodes_to_wait]
|
|
317
|
-
if issubclass(prev_nodes.__class__,TriccBaseModel):
|
|
352
|
+
if issubclass(prev_nodes.__class__, TriccBaseModel):
|
|
318
353
|
prev_nodes = set([prev_nodes])
|
|
319
354
|
elif isinstance(prev_nodes, list):
|
|
320
355
|
prev_nodes = set(prev_nodes)
|
|
321
|
-
|
|
356
|
+
|
|
322
357
|
iterator = iter(prev_nodes)
|
|
323
358
|
prev_node = next(iterator)
|
|
324
359
|
path = prev_node if len(prev_nodes) == 1 else get_bridge_path(prev_nodes, activity)
|
|
325
|
-
|
|
360
|
+
|
|
326
361
|
activity = activity or prev_node.activity
|
|
327
362
|
calc_node = TriccNodeWait(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
363
|
+
id=generate_id(f"ar{''.join([x.id for x in nodes_to_wait])}{activity.id}"),
|
|
364
|
+
reference=nodes_to_wait,
|
|
365
|
+
activity=activity,
|
|
366
|
+
group=activity,
|
|
367
|
+
path=path,
|
|
368
|
+
)
|
|
334
369
|
|
|
335
|
-
#start the wait and the next_nodes from the prev_nodes
|
|
336
|
-
#add the wait as dependency of the next_nodes
|
|
370
|
+
# start the wait and the next_nodes from the prev_nodes
|
|
371
|
+
# add the wait as dependency of the next_nodes
|
|
337
372
|
|
|
338
|
-
|
|
373
|
+
# add edge between rhombus and node
|
|
339
374
|
|
|
340
|
-
set_prev_next_node(path,calc_node, edge_only=edge_only, activity=activity
|
|
375
|
+
set_prev_next_node(path, calc_node, edge_only=edge_only, activity=activity)
|
|
341
376
|
for next_node in next_nodes:
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
set_prev_next_node(calc_node,next_node, edge_only=edge_only,activity=activity)
|
|
347
|
-
|
|
348
|
-
|
|
377
|
+
# if prev != replaced_node and next_node != replaced_node :
|
|
378
|
+
# set_prev_next_node(prev,next_node,replaced_node)
|
|
379
|
+
# if first:
|
|
380
|
+
# first = False
|
|
381
|
+
set_prev_next_node(calc_node, next_node, edge_only=edge_only, activity=activity)
|
|
382
|
+
|
|
349
383
|
return calc_node
|
|
350
|
-
|
|
351
|
-
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def get_bridge_path(prev_nodes, node=None, edge_only=False):
|
|
352
387
|
iterator = iter(prev_nodes)
|
|
353
|
-
p_p_node = next(iterator)
|
|
388
|
+
p_p_node = next(iterator)
|
|
354
389
|
if node is None:
|
|
355
390
|
node = p_p_node
|
|
356
|
-
calc_id
|
|
357
|
-
calc_name = "path_"+calc_id
|
|
391
|
+
calc_id = generate_id(f"br{''.join([x.id for x in prev_nodes])}{node.id}")
|
|
392
|
+
calc_name = "path_" + calc_id
|
|
358
393
|
data = {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
394
|
+
"id": calc_id,
|
|
395
|
+
"group": node.group,
|
|
396
|
+
"activity": node.activity,
|
|
397
|
+
"label": "path: " + (node.get_name()),
|
|
398
|
+
"name": calc_name,
|
|
399
|
+
"path_len": node.path_len + 1 * (node == p_p_node),
|
|
365
400
|
}
|
|
366
|
-
|
|
367
|
-
if
|
|
368
|
-
|
|
401
|
+
|
|
402
|
+
if (
|
|
403
|
+
len(prev_nodes) > 1
|
|
404
|
+
and sum(
|
|
405
|
+
[0 if issubclass(n.__class__, (TriccNodeDisplayCalculateBase, TriccNodeRhombus)) else 1 for n in prev_nodes]
|
|
406
|
+
)
|
|
407
|
+
> 0
|
|
408
|
+
):
|
|
409
|
+
calc = TriccNodeDisplayBridge(**data)
|
|
369
410
|
else:
|
|
370
|
-
calc =
|
|
411
|
+
calc = TriccNodeBridge(**data)
|
|
371
412
|
return calc
|
|
372
|
-
|
|
413
|
+
|
|
414
|
+
|
|
373
415
|
def inject_bridge_path(node, nodes):
|
|
374
416
|
|
|
375
|
-
prev_nodes = [
|
|
417
|
+
prev_nodes = [
|
|
418
|
+
nodes[n.source]
|
|
419
|
+
for n in list(
|
|
420
|
+
filter(
|
|
421
|
+
lambda x: (x.target == node.id or x.target == node) and x.source in list(nodes.keys()),
|
|
422
|
+
node.activity.edges,
|
|
423
|
+
)
|
|
424
|
+
)
|
|
425
|
+
]
|
|
376
426
|
if prev_nodes:
|
|
377
|
-
calc = get_bridge_path(prev_nodes, node,edge_only=True)
|
|
427
|
+
calc = get_bridge_path(prev_nodes, node, edge_only=True)
|
|
378
428
|
|
|
379
429
|
for e in node.activity.edges:
|
|
380
430
|
if e.target == node.id:
|
|
381
431
|
# if e.source in node.activity.nodes and len(node.activity.nodes[e.source].next_nodes):
|
|
382
432
|
# set_prev_next_node(node.activity[e.source], node, edge_only=True, replaced_node=node)
|
|
383
433
|
# else:
|
|
384
|
-
|
|
385
|
-
|
|
434
|
+
e.target = calc.id
|
|
435
|
+
|
|
386
436
|
# add edge between bridge and node
|
|
387
|
-
set_prev_next_node(calc,node,edge_only=True, activity=node.activity)
|
|
437
|
+
set_prev_next_node(calc, node, edge_only=True, activity=node.activity)
|
|
388
438
|
node.path_len += 1
|
|
389
439
|
return calc
|
|
390
440
|
|
|
@@ -394,45 +444,50 @@ def inject_node_before(before, node, activity):
|
|
|
394
444
|
before.activity = activity
|
|
395
445
|
activity.nodes[before.id] = before
|
|
396
446
|
nodes = activity.nodes
|
|
397
|
-
prev_nodes = node.prev_nodes.union(
|
|
447
|
+
prev_nodes = node.prev_nodes.union(
|
|
448
|
+
set(
|
|
449
|
+
nodes[n.source]
|
|
450
|
+
for n in list(
|
|
451
|
+
filter(lambda x: (x.target == node.id or x.target == node) and x.source in nodes, node.activity.edges)
|
|
452
|
+
)
|
|
453
|
+
)
|
|
454
|
+
)
|
|
398
455
|
edge_processed = False
|
|
399
456
|
before.path_len = node.path_len
|
|
400
457
|
for e in node.activity.edges:
|
|
401
458
|
if e.target == node.id:
|
|
402
459
|
e.target = before.id
|
|
403
|
-
for p in prev_nodes:
|
|
404
|
-
prev_processed = len(node.next_nodes) > 0
|
|
460
|
+
for p in prev_nodes:
|
|
405
461
|
if node in p.next_nodes:
|
|
406
462
|
p.next_nodes.remove(node)
|
|
407
463
|
p.next_nodes.append(before)
|
|
408
464
|
|
|
409
465
|
# add edge between bridge and node
|
|
410
|
-
set_prev_next_node(before,node,edge_only=not edge_processed, activity=node.activity)
|
|
466
|
+
set_prev_next_node(before, node, edge_only=not edge_processed, activity=node.activity)
|
|
411
467
|
node.path_len += 1
|
|
412
468
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
def generate_calculates(node,calculates, used_calculates,processed_nodes, process):
|
|
469
|
+
|
|
470
|
+
def generate_calculates(node, calculates, used_calculates, processed_nodes, process):
|
|
416
471
|
list_calc = []
|
|
417
472
|
count_node = None
|
|
418
|
-
|
|
473
|
+
# add select calcualte
|
|
419
474
|
if issubclass(node.__class__, TriccNodeCalculateBase):
|
|
420
475
|
if isinstance(node, TriccNodeRhombus):
|
|
421
476
|
if (
|
|
422
477
|
(node.expression_reference is None or isinstance(node.expression_reference, TriccOperation))
|
|
423
478
|
and isinstance(node.reference, list)
|
|
424
|
-
and len(node.reference)==1
|
|
479
|
+
and len(node.reference) == 1
|
|
425
480
|
and issubclass(node.reference[0].__class__, TriccNodeSelect)
|
|
426
481
|
):
|
|
427
482
|
|
|
428
483
|
count_node = get_count_node(node)
|
|
429
484
|
list_calc.append(count_node)
|
|
430
|
-
set_prev_next_node(node.reference[0],count_node)
|
|
431
|
-
node.path_len+=1
|
|
432
|
-
|
|
485
|
+
set_prev_next_node(node.reference[0], count_node)
|
|
486
|
+
node.path_len += 1
|
|
487
|
+
|
|
433
488
|
if isinstance(node.expression_reference, TriccOperation):
|
|
434
489
|
node.expression_reference.replace_node(node.reference, count_node)
|
|
435
|
-
node.reference[0] =
|
|
490
|
+
node.reference[0] = count_node
|
|
436
491
|
# elif isinstance(node.reference, TriccOperation):
|
|
437
492
|
# references = node.reference.get_references()
|
|
438
493
|
# if len(references) == 1 and issubclass(node.reference[0].__class__, TriccNodeSelect):
|
|
@@ -445,68 +500,67 @@ def generate_calculates(node,calculates, used_calculates,processed_nodes, proces
|
|
|
445
500
|
processed_nodes.add(count_node)
|
|
446
501
|
add_calculate(calculates, count_node)
|
|
447
502
|
add_used_calculate(
|
|
448
|
-
node,
|
|
449
|
-
count_node,
|
|
450
|
-
calculates=calculates,
|
|
503
|
+
node,
|
|
504
|
+
count_node,
|
|
505
|
+
calculates=calculates,
|
|
451
506
|
used_calculates=used_calculates,
|
|
452
|
-
processed_nodes=processed_nodes
|
|
507
|
+
processed_nodes=processed_nodes,
|
|
453
508
|
)
|
|
454
|
-
|
|
455
|
-
|
|
509
|
+
|
|
456
510
|
# if a prev node is a calculate then it must be added in used_calc
|
|
457
511
|
for prev in node.prev_nodes:
|
|
458
512
|
add_used_calculate(
|
|
459
|
-
node,
|
|
460
|
-
prev,
|
|
461
|
-
calculates=calculates,
|
|
462
|
-
used_calculates=used_calculates,
|
|
463
|
-
processed_nodes=processed_nodes
|
|
513
|
+
node, prev, calculates=calculates, used_calculates=used_calculates, processed_nodes=processed_nodes
|
|
464
514
|
)
|
|
465
|
-
#if the node have a save
|
|
466
|
-
if hasattr(node,
|
|
515
|
+
# if the node have a save
|
|
516
|
+
if hasattr(node, "save") and node.save is not None and node.save != "":
|
|
467
517
|
# get fragments type.name.icdcode
|
|
468
|
-
calculate_name=node.save
|
|
518
|
+
calculate_name = node.save
|
|
469
519
|
if node.name != calculate_name:
|
|
470
520
|
calc_id = generate_id(f"autosave{node.id}")
|
|
471
521
|
if issubclass(node.__class__, TriccNodeSelect) or isinstance(node, TriccNodeSelectNotAvailable):
|
|
472
|
-
expression = get_count_terms_details(
|
|
522
|
+
expression = get_count_terms_details(node, processed_nodes, True, False, process)
|
|
473
523
|
else:
|
|
474
|
-
expression = get_node_expression(node,processed_nodes,True,True)
|
|
524
|
+
expression = get_node_expression(node, processed_nodes, True, True)
|
|
475
525
|
calc_node = TriccNodeCalculate(
|
|
476
526
|
name=calculate_name,
|
|
477
|
-
id
|
|
478
|
-
group
|
|
479
|
-
#version=get_next_version(calculate_name, processed_nodes, node.version+2),
|
|
480
|
-
activity
|
|
481
|
-
label
|
|
482
|
-
path_len=node.path_len+ 1,
|
|
527
|
+
id=calc_id,
|
|
528
|
+
group=node.group,
|
|
529
|
+
# version=get_next_version(calculate_name, processed_nodes, node.version+2),
|
|
530
|
+
activity=node.activity,
|
|
531
|
+
label="save: " + node.get_name(),
|
|
532
|
+
path_len=node.path_len + 1,
|
|
483
533
|
last=True,
|
|
484
|
-
expression=expression
|
|
534
|
+
expression=expression,
|
|
485
535
|
)
|
|
486
536
|
node.activity.calculates.append(calc_node)
|
|
487
537
|
last_version = set_last_version_false(calc_node, processed_nodes)
|
|
488
538
|
if last_version:
|
|
489
539
|
calc_node.expression = merge_expression(calc_node.expression, last_version)
|
|
490
540
|
processed_nodes.add(calc_node)
|
|
491
|
-
logger.debug(
|
|
492
|
-
|
|
541
|
+
logger.debug(
|
|
542
|
+
"generate_save_calculate:{}:{} as {}".format(
|
|
543
|
+
calc_node.tricc_type, node.name if hasattr(node, "name") else node.id, calculate_name
|
|
544
|
+
)
|
|
545
|
+
)
|
|
546
|
+
|
|
493
547
|
list_calc.append(calc_node)
|
|
494
|
-
#add_save_calculate(calc_node, calculates, used_calculates,processed_nodes)
|
|
548
|
+
# add_save_calculate(calc_node, calculates, used_calculates,processed_nodes)
|
|
495
549
|
for calc in list_calc:
|
|
496
550
|
node.activity.nodes[calc.id] = calc
|
|
497
551
|
add_calculate(calculates, calc)
|
|
498
552
|
return list_calc
|
|
499
553
|
|
|
500
554
|
|
|
501
|
-
|
|
502
555
|
def add_calculate(calculates, calc_node):
|
|
503
556
|
if issubclass(calc_node.__class__, TriccNodeDisplayCalculateBase):
|
|
504
557
|
if calc_node.name not in calculates:
|
|
505
|
-
calculates[calc_node.name]= {}
|
|
558
|
+
calculates[calc_node.name] = {}
|
|
506
559
|
calculates[calc_node.name][calc_node.id] = calc_node
|
|
507
560
|
|
|
561
|
+
|
|
508
562
|
def get_option_code_from_label(node, option_label):
|
|
509
|
-
if hasattr(node,
|
|
563
|
+
if hasattr(node, "options"):
|
|
510
564
|
for i in node.options:
|
|
511
565
|
if node.options[i].label.strip() == option_label.strip():
|
|
512
566
|
return node.options[i].name
|
|
@@ -515,43 +569,95 @@ def get_option_code_from_label(node, option_label):
|
|
|
515
569
|
logger.critical(f"node {node.get_name()} has no options")
|
|
516
570
|
|
|
517
571
|
|
|
518
|
-
|
|
519
|
-
|
|
572
|
+
# CQL is deined as a cql library and this code will
|
|
573
|
+
# parse the definition and will extract the logic under the define statement
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def extract_with_regex(data):
|
|
577
|
+
text = data
|
|
578
|
+
# Pattern to match define statement and capture the name and body
|
|
579
|
+
pattern = r'define\s+"([^"]+)":\s*(.*)'
|
|
580
|
+
match = re.search(pattern, text, re.DOTALL)
|
|
581
|
+
|
|
582
|
+
if match:
|
|
583
|
+
definition_name = match.group(1)
|
|
584
|
+
definition_body = match.group(2).strip()
|
|
585
|
+
return {"name": definition_name, "body": definition_body, "full": match.group(0)}
|
|
586
|
+
return None
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
def process_reference(
|
|
590
|
+
node, processed_nodes, calculates, used_calculates=None, replace_reference=False, warn=False, codesystems=None
|
|
591
|
+
):
|
|
592
|
+
# process a remote reference coded as a cql
|
|
593
|
+
if getattr(node, "remote_reference", None):
|
|
594
|
+
remote_reference_url = node.remote_reference
|
|
595
|
+
print(f"Fetching remote reference from {remote_reference_url}")
|
|
596
|
+
response = requests.get(remote_reference_url)
|
|
597
|
+
response_json = response.json()
|
|
598
|
+
cql_content = response_json["content"][0]["data"]
|
|
599
|
+
decode_cql_content = base64.b64decode(cql_content).decode("utf-8")
|
|
600
|
+
definition = extract_with_regex(decode_cql_content)
|
|
601
|
+
|
|
602
|
+
if definition:
|
|
603
|
+
cql_expression = definition["body"]
|
|
604
|
+
|
|
605
|
+
# We use `transform_cql_to_operation` to parse the raw CQL string.
|
|
606
|
+
operation = transform_cql_to_operation(cql_expression, context=f"remote reference for {node.get_name()}")
|
|
607
|
+
|
|
608
|
+
if not operation:
|
|
609
|
+
logger.error(f"Failed to parse remote CQL expression for node {node.get_name()}: {cql_expression}")
|
|
610
|
+
return False
|
|
611
|
+
|
|
612
|
+
# The parsed operation is assigned to `expression_reference`.
|
|
613
|
+
# The original code incorrectly assigned the raw string to `node.reference`
|
|
614
|
+
# and had an unreachable `if isinstance(cql_expression, list):` block.
|
|
615
|
+
node.expression_reference = operation
|
|
616
|
+
node.remote_reference = None
|
|
617
|
+
|
|
618
|
+
# By setting `expression_reference` and clearing `remote_reference`,
|
|
619
|
+
# we can now re-process this node. A recursive call to `process_reference`
|
|
620
|
+
# will now enter the `elif getattr(node, 'expression_reference', None):`
|
|
621
|
+
# block, which will correctly handle the newly parsed expression.
|
|
622
|
+
return process_reference(
|
|
623
|
+
node, processed_nodes, calculates, used_calculates, replace_reference, warn, codesystems
|
|
624
|
+
)
|
|
625
|
+
|
|
626
|
+
elif getattr(node, "expression_reference", None):
|
|
520
627
|
modified_expression = process_operation_reference(
|
|
521
|
-
node.expression_reference,
|
|
522
|
-
node,
|
|
628
|
+
node.expression_reference,
|
|
629
|
+
node,
|
|
523
630
|
processed_nodes=processed_nodes,
|
|
524
|
-
calculates=calculates,
|
|
525
|
-
used_calculates=used_calculates,
|
|
631
|
+
calculates=calculates,
|
|
632
|
+
used_calculates=used_calculates,
|
|
526
633
|
replace_reference=replace_reference,
|
|
527
|
-
warn=warn,
|
|
528
|
-
codesystems=codesystems
|
|
634
|
+
warn=warn,
|
|
635
|
+
codesystems=codesystems,
|
|
529
636
|
)
|
|
530
637
|
if modified_expression is False:
|
|
531
638
|
return False
|
|
532
639
|
elif modified_expression and replace_reference:
|
|
533
640
|
node.reference = list(modified_expression.get_references())
|
|
534
641
|
node.expression_reference = modified_expression
|
|
535
|
-
|
|
642
|
+
|
|
643
|
+
elif getattr(node, "reference", None):
|
|
536
644
|
reference = node.reference
|
|
537
645
|
if isinstance(reference, list):
|
|
538
646
|
if isinstance(node, TriccNodeWait):
|
|
539
|
-
reference = [TriccOperation(TriccOperator.ISTRUE,[n]) for n in reference]
|
|
540
|
-
if len(node.reference) == 1
|
|
647
|
+
reference = [TriccOperation(TriccOperator.ISTRUE, [n]) for n in reference]
|
|
648
|
+
if len(node.reference) == 1:
|
|
541
649
|
operation = reference[0]
|
|
542
650
|
else:
|
|
543
|
-
operation = and_join(
|
|
544
|
-
reference
|
|
545
|
-
)
|
|
651
|
+
operation = and_join(reference)
|
|
546
652
|
modified_expression = process_operation_reference(
|
|
547
|
-
operation,
|
|
653
|
+
operation,
|
|
548
654
|
node,
|
|
549
655
|
processed_nodes=processed_nodes,
|
|
550
|
-
calculates=calculates,
|
|
551
|
-
used_calculates=used_calculates,
|
|
656
|
+
calculates=calculates,
|
|
657
|
+
used_calculates=used_calculates,
|
|
552
658
|
replace_reference=replace_reference,
|
|
553
|
-
warn=warn,
|
|
554
|
-
codesystems=codesystems
|
|
659
|
+
warn=warn,
|
|
660
|
+
codesystems=codesystems,
|
|
555
661
|
)
|
|
556
662
|
if modified_expression is False:
|
|
557
663
|
return False
|
|
@@ -561,14 +667,14 @@ def process_reference(node, processed_nodes, calculates, used_calculates=None,
|
|
|
561
667
|
node.expression_reference = modified_expression
|
|
562
668
|
elif isinstance(node.reference, (TriccOperation, TriccReference)):
|
|
563
669
|
modified_expression = process_operation_reference(
|
|
564
|
-
node.reference,
|
|
565
|
-
node,
|
|
670
|
+
node.reference,
|
|
671
|
+
node,
|
|
566
672
|
processed_nodes=processed_nodes,
|
|
567
|
-
calculates=calculates,
|
|
568
|
-
used_calculates=used_calculates,
|
|
673
|
+
calculates=calculates,
|
|
674
|
+
used_calculates=used_calculates,
|
|
569
675
|
replace_reference=replace_reference,
|
|
570
|
-
warn=warn,
|
|
571
|
-
codesystems=codesystems
|
|
676
|
+
warn=warn,
|
|
677
|
+
codesystems=codesystems,
|
|
572
678
|
)
|
|
573
679
|
if modified_expression is False:
|
|
574
680
|
return False
|
|
@@ -576,95 +682,95 @@ def process_reference(node, processed_nodes, calculates, used_calculates=None,
|
|
|
576
682
|
node.reference = list(modified_expression.get_references())
|
|
577
683
|
node.expression_reference = modified_expression
|
|
578
684
|
|
|
579
|
-
if isinstance(getattr(node,
|
|
685
|
+
if isinstance(getattr(node, "relevance", None), (TriccOperation, TriccReference)):
|
|
580
686
|
modified_expression = process_operation_reference(
|
|
581
|
-
node.relevance,
|
|
582
|
-
node,
|
|
687
|
+
node.relevance,
|
|
688
|
+
node,
|
|
583
689
|
processed_nodes=processed_nodes,
|
|
584
|
-
calculates=calculates,
|
|
585
|
-
used_calculates=used_calculates,
|
|
690
|
+
calculates=calculates,
|
|
691
|
+
used_calculates=used_calculates,
|
|
586
692
|
replace_reference=replace_reference,
|
|
587
|
-
warn=warn,
|
|
588
|
-
codesystems=codesystems
|
|
693
|
+
warn=warn,
|
|
694
|
+
codesystems=codesystems,
|
|
589
695
|
)
|
|
590
696
|
if modified_expression is False:
|
|
591
697
|
return False
|
|
592
698
|
elif modified_expression and replace_reference:
|
|
593
699
|
node.relevance = modified_expression
|
|
594
|
-
|
|
595
|
-
if isinstance(getattr(node,
|
|
700
|
+
|
|
701
|
+
if isinstance(getattr(node, "trigger", None), (TriccOperation, TriccReference)):
|
|
596
702
|
modified_expression = process_operation_reference(
|
|
597
|
-
node.trigger,
|
|
598
|
-
node,
|
|
703
|
+
node.trigger,
|
|
704
|
+
node,
|
|
599
705
|
processed_nodes=processed_nodes,
|
|
600
|
-
calculates=calculates,
|
|
601
|
-
used_calculates=used_calculates,
|
|
706
|
+
calculates=calculates,
|
|
707
|
+
used_calculates=used_calculates,
|
|
602
708
|
replace_reference=replace_reference,
|
|
603
|
-
warn=warn,
|
|
604
|
-
codesystems=codesystems
|
|
709
|
+
warn=warn,
|
|
710
|
+
codesystems=codesystems,
|
|
605
711
|
)
|
|
606
712
|
if modified_expression is False:
|
|
607
713
|
return False
|
|
608
714
|
elif modified_expression and replace_reference:
|
|
609
715
|
node.trigger = modified_expression
|
|
610
|
-
if isinstance(getattr(node,
|
|
716
|
+
if isinstance(getattr(node, "constraint", None), (TriccOperation, TriccReference)):
|
|
611
717
|
modified_expression = process_operation_reference(
|
|
612
|
-
node.constraint,
|
|
613
|
-
node,
|
|
718
|
+
node.constraint,
|
|
719
|
+
node,
|
|
614
720
|
processed_nodes=processed_nodes,
|
|
615
|
-
calculates=calculates,
|
|
616
|
-
used_calculates=used_calculates,
|
|
721
|
+
calculates=calculates,
|
|
722
|
+
used_calculates=used_calculates,
|
|
617
723
|
replace_reference=replace_reference,
|
|
618
|
-
warn=warn,
|
|
619
|
-
codesystems=codesystems
|
|
724
|
+
warn=warn,
|
|
725
|
+
codesystems=codesystems,
|
|
620
726
|
)
|
|
621
727
|
if modified_expression is False:
|
|
622
728
|
return False
|
|
623
729
|
elif modified_expression and replace_reference:
|
|
624
730
|
node.constraint = modified_expression
|
|
625
|
-
|
|
626
|
-
if isinstance(getattr(node,
|
|
731
|
+
|
|
732
|
+
if isinstance(getattr(node, "default", None), (TriccOperation, TriccReference)):
|
|
627
733
|
modified_expression = process_operation_reference(
|
|
628
|
-
node.default,
|
|
629
|
-
node,
|
|
734
|
+
node.default,
|
|
735
|
+
node,
|
|
630
736
|
processed_nodes=processed_nodes,
|
|
631
|
-
calculates=calculates,
|
|
632
|
-
used_calculates=used_calculates,
|
|
737
|
+
calculates=calculates,
|
|
738
|
+
used_calculates=used_calculates,
|
|
633
739
|
replace_reference=replace_reference,
|
|
634
|
-
warn=warn,
|
|
635
|
-
codesystems=codesystems
|
|
636
|
-
)
|
|
740
|
+
warn=warn,
|
|
741
|
+
codesystems=codesystems,
|
|
742
|
+
)
|
|
637
743
|
if modified_expression is False:
|
|
638
744
|
return False
|
|
639
745
|
elif modified_expression and replace_reference:
|
|
640
746
|
node.relevance = modified_expression
|
|
641
|
-
|
|
642
|
-
if isinstance(getattr(node,
|
|
747
|
+
|
|
748
|
+
if isinstance(getattr(node, "expression", None), (TriccOperation, TriccReference)):
|
|
643
749
|
modified_expression = process_operation_reference(
|
|
644
|
-
node.expression,
|
|
645
|
-
node,
|
|
750
|
+
node.expression,
|
|
751
|
+
node,
|
|
646
752
|
processed_nodes=processed_nodes,
|
|
647
|
-
calculates=calculates,
|
|
648
|
-
used_calculates=used_calculates,
|
|
753
|
+
calculates=calculates,
|
|
754
|
+
used_calculates=used_calculates,
|
|
649
755
|
replace_reference=replace_reference,
|
|
650
|
-
warn=warn,
|
|
651
|
-
codesystems=codesystems
|
|
756
|
+
warn=warn,
|
|
757
|
+
codesystems=codesystems,
|
|
652
758
|
)
|
|
653
759
|
if modified_expression is False:
|
|
654
760
|
return False
|
|
655
761
|
elif modified_expression and replace_reference:
|
|
656
762
|
node.expression = modified_expression
|
|
657
|
-
|
|
658
|
-
if isinstance(getattr(node,
|
|
763
|
+
|
|
764
|
+
if isinstance(getattr(node, "applicability", None), (TriccOperation, TriccReference)):
|
|
659
765
|
modified_expression = process_operation_reference(
|
|
660
|
-
node.applicability,
|
|
661
|
-
node,
|
|
766
|
+
node.applicability,
|
|
767
|
+
node,
|
|
662
768
|
processed_nodes=processed_nodes,
|
|
663
|
-
calculates=calculates,
|
|
664
|
-
used_calculates=used_calculates,
|
|
769
|
+
calculates=calculates,
|
|
770
|
+
used_calculates=used_calculates,
|
|
665
771
|
replace_reference=replace_reference,
|
|
666
|
-
warn=warn,
|
|
667
|
-
codesystems=codesystems
|
|
772
|
+
warn=warn,
|
|
773
|
+
codesystems=codesystems,
|
|
668
774
|
)
|
|
669
775
|
if modified_expression is False:
|
|
670
776
|
return False
|
|
@@ -672,7 +778,17 @@ def process_reference(node, processed_nodes, calculates, used_calculates=None,
|
|
|
672
778
|
node.applicability = modified_expression
|
|
673
779
|
return True
|
|
674
780
|
|
|
675
|
-
|
|
781
|
+
|
|
782
|
+
def process_operation_reference(
|
|
783
|
+
operation,
|
|
784
|
+
node,
|
|
785
|
+
processed_nodes,
|
|
786
|
+
calculates,
|
|
787
|
+
used_calculates=None,
|
|
788
|
+
replace_reference=False,
|
|
789
|
+
warn=False,
|
|
790
|
+
codesystems=None,
|
|
791
|
+
):
|
|
676
792
|
modified_operation = None
|
|
677
793
|
node_reference = []
|
|
678
794
|
reference = []
|
|
@@ -680,13 +796,13 @@ def process_operation_reference(operation, node, processed_nodes, calculates, us
|
|
|
680
796
|
ref_list = [r.value for r in operation.get_references() if isinstance(r, TriccReference)]
|
|
681
797
|
real_ref_list = [r for r in operation.get_references() if issubclass(r.__class__, TriccNodeBaseModel)]
|
|
682
798
|
for ref in ref_list:
|
|
683
|
-
if ref.endswith(
|
|
684
|
-
terms = ref[:-1].split(
|
|
799
|
+
if ref.endswith("]"):
|
|
800
|
+
terms = ref[:-1].split("[")
|
|
685
801
|
option_label = terms[1]
|
|
686
802
|
ref = terms[0]
|
|
687
803
|
else:
|
|
688
804
|
option_label = None
|
|
689
|
-
node_in_act = [n for n in node.activity.nodes.values() if n.name == ref and n != node]
|
|
805
|
+
node_in_act = [n for n in node.activity.nodes.values() if n.name == ref and n != node]
|
|
690
806
|
if node_in_act:
|
|
691
807
|
if any(n not in processed_nodes for n in node_in_act):
|
|
692
808
|
return False
|
|
@@ -694,16 +810,16 @@ def process_operation_reference(operation, node, processed_nodes, calculates, us
|
|
|
694
810
|
last_found = node_in_act[0]
|
|
695
811
|
else:
|
|
696
812
|
last_found = get_last_version(name=ref, processed_nodes=processed_nodes)
|
|
697
|
-
if last_found is None:
|
|
813
|
+
if last_found is None:
|
|
698
814
|
if codesystems:
|
|
699
|
-
concept =
|
|
815
|
+
concept = lookup_codesystems_code(codesystems, ref)
|
|
700
816
|
if not concept:
|
|
701
817
|
logger.critical(f"reference {ref} not found in the project for{str(node)} ")
|
|
702
818
|
exit(1)
|
|
703
819
|
else:
|
|
704
820
|
if warn:
|
|
705
821
|
logger.debug(f"reference {ref}::{concept.display} not yet processed {node.get_name()}")
|
|
706
|
-
|
|
822
|
+
|
|
707
823
|
elif warn:
|
|
708
824
|
logger.debug(f"reference {ref} not found for a calculate {node.get_name()}")
|
|
709
825
|
return False
|
|
@@ -711,7 +827,9 @@ def process_operation_reference(operation, node, processed_nodes, calculates, us
|
|
|
711
827
|
node_reference.append(last_found)
|
|
712
828
|
reference.append(TriccReference(ref))
|
|
713
829
|
if replace_reference:
|
|
714
|
-
if not issubclass(
|
|
830
|
+
if not issubclass(
|
|
831
|
+
last_found.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase, TriccNodeInput)
|
|
832
|
+
):
|
|
715
833
|
last_found = get_node_expression(last_found, processed_nodes, is_prev=True)
|
|
716
834
|
if isinstance(operation, (TriccOperation)):
|
|
717
835
|
if modified_operation is None:
|
|
@@ -723,118 +841,141 @@ def process_operation_reference(operation, node, processed_nodes, calculates, us
|
|
|
723
841
|
# Resolve human-readable label
|
|
724
842
|
option_code = get_option_code_from_label(last_found, option_label)
|
|
725
843
|
if option_code:
|
|
726
|
-
modified_operation = replace_code_reference(
|
|
844
|
+
modified_operation = replace_code_reference(
|
|
845
|
+
operation, old=f"{ref}[{option_label}]", new=option_code
|
|
846
|
+
)
|
|
727
847
|
else:
|
|
728
848
|
if warn:
|
|
729
849
|
logger.warning(f"Could not resolve label '{option_label}' for reference {ref}")
|
|
730
850
|
return False
|
|
731
|
-
if hasattr(last_found,
|
|
732
|
-
path_len = last_found.path_len
|
|
851
|
+
if hasattr(last_found, "path_len"):
|
|
852
|
+
path_len = last_found.path_len
|
|
733
853
|
elif isinstance(last_found, TriccOperation):
|
|
734
|
-
path_len =
|
|
854
|
+
path_len = max(getattr(n, "path_len", 0) for n in last_found.get_references())
|
|
735
855
|
else:
|
|
736
856
|
path_len = 0
|
|
737
857
|
node.path_len = max(node.path_len, path_len)
|
|
738
858
|
for ref in real_ref_list:
|
|
739
859
|
if is_prev_processed(ref, node, processed_nodes=processed_nodes, local=False) is False:
|
|
740
860
|
return False
|
|
741
|
-
|
|
861
|
+
|
|
742
862
|
if used_calculates is not None:
|
|
743
863
|
for ref_nodes in node_reference:
|
|
744
864
|
if issubclass(ref_nodes.__class__, TriccNodeCalculateBase):
|
|
745
865
|
add_used_calculate(node, ref_nodes, calculates, used_calculates, processed_nodes=processed_nodes)
|
|
746
866
|
return modified_operation
|
|
747
867
|
|
|
868
|
+
|
|
748
869
|
def replace_code_reference(expression, old, new):
|
|
749
870
|
if isinstance(expression, str):
|
|
750
|
-
return
|
|
871
|
+
return expression.replace(old, f"'{new}'")
|
|
751
872
|
if isinstance(expression, TriccOperation):
|
|
752
873
|
expression.replace_node(TriccReference(old), TriccStatic(new))
|
|
753
874
|
return expression
|
|
754
|
-
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
# add_used_calculate(node, calc_node, calculates, used_calculates, processed_nodes)
|
|
878
|
+
|
|
755
879
|
|
|
756
880
|
def add_used_calculate(node, prev_node, calculates, used_calculates, processed_nodes):
|
|
757
881
|
if issubclass(prev_node.__class__, TriccNodeDisplayCalculateBase):
|
|
758
882
|
if prev_node in processed_nodes:
|
|
759
883
|
# if not a verison, index will equal -1
|
|
760
|
-
if prev_node.name not in calculates
|
|
884
|
+
if prev_node.name not in calculates:
|
|
761
885
|
logger.debug("node {} refered before being processed".format(node.get_name()))
|
|
762
886
|
return False
|
|
763
|
-
max_version = prev_node#get_max_version(calculates[node_clean_name])
|
|
887
|
+
max_version = prev_node # get_max_version(calculates[node_clean_name])
|
|
764
888
|
if prev_node.name not in used_calculates:
|
|
765
889
|
used_calculates[prev_node.name] = {}
|
|
766
|
-
#save the max version only once
|
|
890
|
+
# save the max version only once
|
|
767
891
|
if max_version.id not in used_calculates[prev_node.name]:
|
|
768
892
|
used_calculates[prev_node.name][max_version.id] = max_version
|
|
769
893
|
else:
|
|
770
|
-
logger.debug(
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
894
|
+
logger.debug(
|
|
895
|
+
"process_calculate_version_requirement: failed for {0} , prev Node {1} ".format(
|
|
896
|
+
node.get_name(), prev_node.get_name()
|
|
897
|
+
)
|
|
898
|
+
)
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
def get_select_not_available_options(node, group, label):
|
|
902
|
+
return {
|
|
903
|
+
0: TriccNodeSelectOption(
|
|
904
|
+
id=generate_id(f"notavaialble{node.id}"),
|
|
905
|
+
name="1",
|
|
906
|
+
label=label,
|
|
907
|
+
select=node,
|
|
908
|
+
group=group,
|
|
909
|
+
list_name=node.list_name,
|
|
910
|
+
)
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
|
|
783
914
|
def get_select_yes_no_options(node, group):
|
|
784
915
|
yes = TriccNodeSelectOption(
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
916
|
+
id=generate_id(f"yes{node.id}"),
|
|
917
|
+
name=f"{TRICC_TRUE_VALUE}",
|
|
918
|
+
label="Yes",
|
|
919
|
+
select=node,
|
|
920
|
+
group=group,
|
|
921
|
+
list_name=node.list_name,
|
|
922
|
+
)
|
|
792
923
|
no = TriccNodeSelectOption(
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
return {0:yes, 1:no
|
|
924
|
+
id=generate_id(f"no{node.id}"),
|
|
925
|
+
name=f"{TRICC_FALSE_VALUE}",
|
|
926
|
+
label="No",
|
|
927
|
+
select=node,
|
|
928
|
+
group=group,
|
|
929
|
+
list_name=node.list_name,
|
|
930
|
+
)
|
|
931
|
+
return {0: yes, 1: no}
|
|
932
|
+
|
|
801
933
|
|
|
802
|
-
# walkthough all node in an iterative way, the same node might be parsed 2 times
|
|
934
|
+
# walkthough all node in an iterative way, the same node might be parsed 2 times
|
|
803
935
|
# therefore to avoid double processing the nodes variable saves the node already processed
|
|
804
936
|
# there 2 strategies : process it the first time or the last time (wait that all the previuous node are processed)
|
|
805
937
|
|
|
806
|
-
|
|
807
|
-
|
|
938
|
+
|
|
939
|
+
def walktrhough_tricc_node_processed_stached(
|
|
940
|
+
node,
|
|
941
|
+
callback,
|
|
942
|
+
processed_nodes,
|
|
943
|
+
stashed_nodes,
|
|
944
|
+
path_len,
|
|
945
|
+
recursive=False,
|
|
946
|
+
warn=False,
|
|
947
|
+
node_path=[],
|
|
948
|
+
process=None,
|
|
949
|
+
**kwargs,
|
|
950
|
+
):
|
|
808
951
|
ended_activity = False
|
|
809
952
|
# logger.debug("walkthrough::{}::{}".format(callback.__name__, node.get_name()))
|
|
810
|
-
|
|
811
|
-
path_len = max(node.activity.path_len, *[0
|
|
812
|
-
if hasattr(node,
|
|
813
|
-
path_len = max(path_len, *[0
|
|
814
|
-
if hasattr(node,
|
|
953
|
+
|
|
954
|
+
path_len = max(node.activity.path_len, *[0, *[getattr(n, "path_len", 0) + 1 for n in node.activity.prev_nodes]]) + 1
|
|
955
|
+
if hasattr(node, "prev_nodes"):
|
|
956
|
+
path_len = max(path_len, *[0, *[getattr(n, "path_len", 0) + 1 for n in node.prev_nodes]])
|
|
957
|
+
if hasattr(node, "get_references"):
|
|
815
958
|
references = node.get_references()
|
|
816
959
|
if references:
|
|
817
|
-
path_len = max(path_len, *[0
|
|
960
|
+
path_len = max(path_len, *[0, *[getattr(n, "path_len", 0) + 1 for n in references]])
|
|
818
961
|
node.path_len = max(node.path_len, path_len)
|
|
819
962
|
prev_process = process[0] if process else None
|
|
820
|
-
if isinstance(node, TriccNodeActivity) and getattr(node.root,
|
|
963
|
+
if isinstance(node, TriccNodeActivity) and getattr(node.root, "process", None):
|
|
821
964
|
if process is None:
|
|
822
965
|
process = [node.root.process]
|
|
823
966
|
else:
|
|
824
967
|
process[0] = node.root.process
|
|
825
|
-
if (
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
**kwargs
|
|
834
|
-
)
|
|
968
|
+
if callback(
|
|
969
|
+
node,
|
|
970
|
+
processed_nodes=processed_nodes,
|
|
971
|
+
stashed_nodes=stashed_nodes,
|
|
972
|
+
warn=warn,
|
|
973
|
+
node_path=node_path,
|
|
974
|
+
process=process,
|
|
975
|
+
**kwargs,
|
|
835
976
|
):
|
|
836
977
|
node_path.append(node)
|
|
837
|
-
# node processing succeed
|
|
978
|
+
# node processing succeed
|
|
838
979
|
if not isinstance(node, TriccNodeActivity) and node not in processed_nodes:
|
|
839
980
|
processed_nodes.add(node)
|
|
840
981
|
if warn:
|
|
@@ -845,7 +986,11 @@ def walktrhough_tricc_node_processed_stached(node, callback, processed_nodes, st
|
|
|
845
986
|
processed_nodes.add(node.activity)
|
|
846
987
|
ended_activity = True
|
|
847
988
|
if warn:
|
|
848
|
-
logger.debug(
|
|
989
|
+
logger.debug(
|
|
990
|
+
"{}::{}: processed ({})".format(
|
|
991
|
+
callback.__name__, node.activity.get_name(), len(processed_nodes)
|
|
992
|
+
)
|
|
993
|
+
)
|
|
849
994
|
elif node in stashed_nodes:
|
|
850
995
|
stashed_nodes.remove(node)
|
|
851
996
|
# logger.debug("{}::{}: unstashed ({})".format(callback.__name__, node.get_name(), len(stashed_nodes)))
|
|
@@ -856,90 +1001,118 @@ def walktrhough_tricc_node_processed_stached(node, callback, processed_nodes, st
|
|
|
856
1001
|
if recursive:
|
|
857
1002
|
for gp in node.activity.groups.values():
|
|
858
1003
|
walktrhough_tricc_node_processed_stached(
|
|
859
|
-
gp,
|
|
1004
|
+
gp,
|
|
860
1005
|
callback,
|
|
861
|
-
processed_nodes=processed_nodes,
|
|
862
|
-
stashed_nodes=stashed_nodes,
|
|
1006
|
+
processed_nodes=processed_nodes,
|
|
1007
|
+
stashed_nodes=stashed_nodes,
|
|
863
1008
|
path_len=path_len,
|
|
864
1009
|
recursive=recursive,
|
|
865
|
-
warn
|
|
866
|
-
node_path
|
|
867
|
-
**kwargs
|
|
1010
|
+
warn=warn,
|
|
1011
|
+
node_path=node_path.copy(),
|
|
1012
|
+
**kwargs,
|
|
868
1013
|
)
|
|
869
1014
|
for c in node.activity.calculates:
|
|
870
|
-
if len(c.prev_nodes)== 0:
|
|
1015
|
+
if len(c.prev_nodes) == 0:
|
|
871
1016
|
walktrhough_tricc_node_processed_stached(
|
|
872
1017
|
c,
|
|
873
1018
|
callback,
|
|
874
|
-
processed_nodes=processed_nodes,
|
|
875
|
-
stashed_nodes=stashed_nodes,
|
|
1019
|
+
processed_nodes=processed_nodes,
|
|
1020
|
+
stashed_nodes=stashed_nodes,
|
|
876
1021
|
path_len=path_len,
|
|
877
1022
|
recursive=recursive,
|
|
878
|
-
warn
|
|
879
|
-
node_path
|
|
880
|
-
**kwargs
|
|
881
|
-
)
|
|
1023
|
+
warn=warn,
|
|
1024
|
+
node_path=node_path.copy(),
|
|
1025
|
+
**kwargs,
|
|
1026
|
+
)
|
|
882
1027
|
else:
|
|
883
|
-
stashed_nodes += [c for c in node.activity.calculates if len(c.prev_nodes)== 0]
|
|
1028
|
+
stashed_nodes += [c for c in node.activity.calculates if len(c.prev_nodes) == 0]
|
|
884
1029
|
stashed_nodes += node.activity.groups.values()
|
|
885
1030
|
elif issubclass(node.__class__, TriccNodeSelect):
|
|
886
1031
|
for option in node.options.values():
|
|
887
|
-
option.path_len = max(path_len,
|
|
888
|
-
callback(
|
|
1032
|
+
option.path_len = max(path_len, option.path_len)
|
|
1033
|
+
callback(
|
|
1034
|
+
option,
|
|
1035
|
+
processed_nodes=processed_nodes,
|
|
1036
|
+
stashed_nodes=stashed_nodes,
|
|
1037
|
+
warn=warn,
|
|
1038
|
+
node_path=node_path,
|
|
1039
|
+
**kwargs,
|
|
1040
|
+
)
|
|
889
1041
|
if option not in processed_nodes:
|
|
890
1042
|
processed_nodes.add(option)
|
|
891
1043
|
if warn:
|
|
892
1044
|
logger.debug(
|
|
893
|
-
"{}::{}: processed ({})".format(callback.__name__, option.get_name(), len(processed_nodes))
|
|
894
|
-
|
|
895
|
-
|
|
1045
|
+
"{}::{}: processed ({})".format(callback.__name__, option.get_name(), len(processed_nodes))
|
|
1046
|
+
)
|
|
1047
|
+
walkthrough_tricc_option(
|
|
1048
|
+
node,
|
|
1049
|
+
callback,
|
|
1050
|
+
processed_nodes,
|
|
1051
|
+
stashed_nodes,
|
|
1052
|
+
path_len + 1,
|
|
1053
|
+
recursive,
|
|
1054
|
+
warn=warn,
|
|
1055
|
+
node_path=node_path,
|
|
1056
|
+
**kwargs,
|
|
1057
|
+
)
|
|
896
1058
|
if isinstance(node, TriccNodeActivity):
|
|
897
1059
|
if node.root not in processed_nodes:
|
|
898
1060
|
if node.root is not None:
|
|
899
|
-
node.root.path_len = max(path_len,
|
|
1061
|
+
node.root.path_len = max(path_len, node.root.path_len)
|
|
900
1062
|
if recursive:
|
|
901
|
-
walktrhough_tricc_node_processed_stached(
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1063
|
+
walktrhough_tricc_node_processed_stached(
|
|
1064
|
+
node.root,
|
|
1065
|
+
callback,
|
|
1066
|
+
processed_nodes,
|
|
1067
|
+
stashed_nodes,
|
|
1068
|
+
path_len,
|
|
1069
|
+
recursive,
|
|
1070
|
+
warn=warn,
|
|
1071
|
+
node_path=node_path.copy(),
|
|
1072
|
+
**kwargs,
|
|
1073
|
+
)
|
|
910
1074
|
elif node.root not in stashed_nodes:
|
|
911
|
-
#stashed_nodes.insert(0,node.root)
|
|
912
1075
|
stashed_nodes.insert_at_top(node.root)
|
|
913
|
-
# if node.calculates:
|
|
914
|
-
# stashed_nodes += node.calculates
|
|
915
|
-
# for gp in node.groups:
|
|
916
|
-
# stashed_nodes.add(gp)
|
|
917
|
-
# # stashed_nodes.insert(0,gp)
|
|
918
1076
|
return
|
|
919
1077
|
elif ended_activity:
|
|
920
1078
|
for next_node in node.next_nodes:
|
|
921
1079
|
if next_node not in stashed_nodes:
|
|
922
|
-
#stashed_nodes.insert(0,next_node)
|
|
1080
|
+
# stashed_nodes.insert(0,next_node)
|
|
923
1081
|
if recursive:
|
|
924
|
-
walktrhough_tricc_node_processed_stached(
|
|
925
|
-
|
|
1082
|
+
walktrhough_tricc_node_processed_stached(
|
|
1083
|
+
next_node,
|
|
1084
|
+
callback,
|
|
1085
|
+
processed_nodes,
|
|
1086
|
+
stashed_nodes,
|
|
1087
|
+
path_len,
|
|
1088
|
+
recursive,
|
|
1089
|
+
warn=warn,
|
|
1090
|
+
node_path=node_path.copy(),
|
|
1091
|
+
**kwargs,
|
|
1092
|
+
)
|
|
926
1093
|
else:
|
|
927
1094
|
stashed_nodes.insert_at_top(next_node)
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
elif hasattr(node, 'next_nodes') and len(node.next_nodes) > 0 and not isinstance(node, TriccNodeActivity):
|
|
1095
|
+
|
|
1096
|
+
elif hasattr(node, "next_nodes") and len(node.next_nodes) > 0 and not isinstance(node, TriccNodeActivity):
|
|
931
1097
|
if recursive:
|
|
932
|
-
walkthrough_tricc_next_nodes(
|
|
933
|
-
|
|
1098
|
+
walkthrough_tricc_next_nodes(
|
|
1099
|
+
node,
|
|
1100
|
+
callback,
|
|
1101
|
+
processed_nodes,
|
|
1102
|
+
stashed_nodes,
|
|
1103
|
+
path_len + 1,
|
|
1104
|
+
recursive,
|
|
1105
|
+
warn=warn,
|
|
1106
|
+
node_path=node_path,
|
|
1107
|
+
**kwargs,
|
|
1108
|
+
)
|
|
934
1109
|
else:
|
|
935
1110
|
for nn in node.next_nodes:
|
|
936
1111
|
if nn not in stashed_nodes:
|
|
937
1112
|
stashed_nodes.insert_at_top(nn)
|
|
938
1113
|
if not recursive:
|
|
939
1114
|
reorder_node_list(stashed_nodes, node.group, processed_nodes)
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1115
|
+
|
|
943
1116
|
else:
|
|
944
1117
|
if prev_process and process and prev_process != process[0]:
|
|
945
1118
|
process[0] = prev_process
|
|
@@ -950,8 +1123,10 @@ def walktrhough_tricc_node_processed_stached(node, callback, processed_nodes, st
|
|
|
950
1123
|
logger.debug("{}::{}: stashed({})".format(callback.__name__, node.get_name(), len(stashed_nodes)))
|
|
951
1124
|
|
|
952
1125
|
|
|
953
|
-
def walkthrough_tricc_next_nodes(
|
|
954
|
-
|
|
1126
|
+
def walkthrough_tricc_next_nodes(
|
|
1127
|
+
node, callback, processed_nodes, stashed_nodes, path_len, recursive, warn=False, node_path=[], **kwargs
|
|
1128
|
+
):
|
|
1129
|
+
|
|
955
1130
|
if not recursive:
|
|
956
1131
|
for next_node in node.next_nodes:
|
|
957
1132
|
if next_node not in stashed_nodes:
|
|
@@ -961,73 +1136,100 @@ def walkthrough_tricc_next_nodes(node, callback, processed_nodes, stashed_nodes,
|
|
|
961
1136
|
for next_node in list_next:
|
|
962
1137
|
if not isinstance(node, (TriccNodeActivityEnd, TriccNodeEnd)):
|
|
963
1138
|
if next_node not in processed_nodes:
|
|
964
|
-
walktrhough_tricc_node_processed_stached(
|
|
965
|
-
|
|
1139
|
+
walktrhough_tricc_node_processed_stached(
|
|
1140
|
+
next_node,
|
|
1141
|
+
callback,
|
|
1142
|
+
processed_nodes,
|
|
1143
|
+
stashed_nodes,
|
|
1144
|
+
path_len + 1,
|
|
1145
|
+
recursive,
|
|
1146
|
+
warn=warn,
|
|
1147
|
+
node_path=node_path.copy(),
|
|
1148
|
+
**kwargs,
|
|
1149
|
+
)
|
|
966
1150
|
else:
|
|
967
1151
|
logger.critical(
|
|
968
|
-
"{}::end node of {} has a next node".format(callback.__name__, node.activity.get_name())
|
|
1152
|
+
"{}::end node of {} has a next node".format(callback.__name__, node.activity.get_name())
|
|
1153
|
+
)
|
|
969
1154
|
exit(1)
|
|
970
1155
|
|
|
971
1156
|
|
|
972
|
-
def walkthrough_tricc_option(
|
|
1157
|
+
def walkthrough_tricc_option(
|
|
1158
|
+
node, callback, processed_nodes, stashed_nodes, path_len, recursive, warn=False, node_path=[], **kwargs
|
|
1159
|
+
):
|
|
973
1160
|
if not recursive:
|
|
974
1161
|
for option in node.options.values():
|
|
975
|
-
if hasattr(option,
|
|
1162
|
+
if hasattr(option, "next_nodes") and len(option.next_nodes) > 0:
|
|
976
1163
|
for next_node in option.next_nodes:
|
|
977
1164
|
if next_node not in stashed_nodes:
|
|
978
1165
|
stashed_nodes.insert_at_top(next_node)
|
|
979
|
-
#stashed_nodes.insert(0,next_node)
|
|
1166
|
+
# stashed_nodes.insert(0,next_node)
|
|
980
1167
|
else:
|
|
981
1168
|
list_option = []
|
|
982
1169
|
while not all(elem in list_option for elem in list(node.options.values())):
|
|
983
1170
|
for option in node.options.values():
|
|
984
1171
|
if option not in list_option:
|
|
985
1172
|
list_option.append(option)
|
|
986
|
-
# then walk the options
|
|
987
|
-
if hasattr(option,
|
|
1173
|
+
# then walk the options
|
|
1174
|
+
if hasattr(option, "next_nodes") and len(option.next_nodes) > 0:
|
|
988
1175
|
list_next = set(option.next_nodes)
|
|
989
1176
|
for next_node in list_next:
|
|
990
1177
|
if next_node not in processed_nodes:
|
|
991
|
-
walktrhough_tricc_node_processed_stached(
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1178
|
+
walktrhough_tricc_node_processed_stached(
|
|
1179
|
+
next_node,
|
|
1180
|
+
callback,
|
|
1181
|
+
processed_nodes,
|
|
1182
|
+
stashed_nodes,
|
|
1183
|
+
path_len + 1,
|
|
1184
|
+
recursive,
|
|
1185
|
+
warn=warn,
|
|
1186
|
+
node_path=node_path.copy(),
|
|
1187
|
+
**kwargs,
|
|
1188
|
+
)
|
|
1189
|
+
|
|
995
1190
|
|
|
996
1191
|
def get_next_version(name, processed_nodes, version=0, min=100):
|
|
997
|
-
return
|
|
1192
|
+
return (
|
|
1193
|
+
max(
|
|
1194
|
+
version,
|
|
1195
|
+
min,
|
|
1196
|
+
*[
|
|
1197
|
+
(getattr(n, "version", None) or getattr(n, "instance", None) or 0)
|
|
1198
|
+
for n in get_versions(name, processed_nodes)
|
|
1199
|
+
],
|
|
1200
|
+
)
|
|
1201
|
+
+ 1
|
|
1202
|
+
)
|
|
998
1203
|
|
|
999
1204
|
|
|
1000
1205
|
def get_data_for_log(node):
|
|
1001
1206
|
return "{}:{}|{} {}:{}".format(
|
|
1002
1207
|
node.group.get_name() if node.group is not None else node.activity.get_name(),
|
|
1003
|
-
node.group.instance if node.group is not None else node.activity.instance
|
|
1208
|
+
node.group.instance if node.group is not None else node.activity.instance,
|
|
1004
1209
|
node.__class__,
|
|
1005
1210
|
node.get_name(),
|
|
1006
|
-
node.instance
|
|
1211
|
+
node.instance,
|
|
1212
|
+
)
|
|
1213
|
+
|
|
1007
1214
|
|
|
1008
1215
|
def stashed_node_func(node, callback, recursive=False, **kwargs):
|
|
1009
|
-
processed_nodes = kwargs.pop(
|
|
1010
|
-
stashed_nodes = kwargs.pop(
|
|
1011
|
-
process = kwargs.pop(
|
|
1216
|
+
processed_nodes = kwargs.pop("processed_nodes", OrderedSet())
|
|
1217
|
+
stashed_nodes = kwargs.pop("stashed_nodes", OrderedSet())
|
|
1218
|
+
process = kwargs.pop("process", ["main"])
|
|
1012
1219
|
path_len = 0
|
|
1013
|
-
|
|
1220
|
+
|
|
1014
1221
|
walktrhough_tricc_node_processed_stached(
|
|
1015
|
-
node,
|
|
1016
|
-
|
|
1017
|
-
processed_nodes,
|
|
1018
|
-
stashed_nodes,
|
|
1019
|
-
path_len,
|
|
1020
|
-
recursive,
|
|
1021
|
-
process=process,
|
|
1022
|
-
**kwargs)
|
|
1222
|
+
node, callback, processed_nodes, stashed_nodes, path_len, recursive, process=process, **kwargs
|
|
1223
|
+
)
|
|
1023
1224
|
# callback( node, **kwargs)
|
|
1024
|
-
|
|
1225
|
+
# MANAGE STASHED NODES
|
|
1025
1226
|
prev_stashed_nodes = stashed_nodes.copy()
|
|
1026
1227
|
loop_count = 0
|
|
1027
1228
|
len_prev_processed_nodes = 0
|
|
1028
1229
|
while len(stashed_nodes) > 0:
|
|
1029
|
-
loop_count = check_stashed_loop(
|
|
1030
|
-
|
|
1230
|
+
loop_count = check_stashed_loop(
|
|
1231
|
+
stashed_nodes, prev_stashed_nodes, processed_nodes, len_prev_processed_nodes, loop_count
|
|
1232
|
+
)
|
|
1031
1233
|
prev_stashed_nodes = stashed_nodes.copy()
|
|
1032
1234
|
len_prev_processed_nodes = len(processed_nodes)
|
|
1033
1235
|
if len(stashed_nodes) > 0:
|
|
@@ -1035,11 +1237,13 @@ def stashed_node_func(node, callback, recursive=False, **kwargs):
|
|
|
1035
1237
|
# remove duplicates
|
|
1036
1238
|
if s_node in stashed_nodes:
|
|
1037
1239
|
stashed_nodes.remove(s_node)
|
|
1038
|
-
if kwargs.get(
|
|
1039
|
-
logger.debug(
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1240
|
+
if kwargs.get("warn", True):
|
|
1241
|
+
logger.debug(
|
|
1242
|
+
"{}:: {}: unstashed for processing ({})::{}".format(
|
|
1243
|
+
callback.__name__, s_node.__class__, get_data_for_log(s_node), len(stashed_nodes)
|
|
1244
|
+
)
|
|
1245
|
+
)
|
|
1246
|
+
warn = loop_count >= (9 * len(stashed_nodes) + 1)
|
|
1043
1247
|
walktrhough_tricc_node_processed_stached(
|
|
1044
1248
|
s_node,
|
|
1045
1249
|
callback,
|
|
@@ -1049,77 +1253,87 @@ def stashed_node_func(node, callback, recursive=False, **kwargs):
|
|
|
1049
1253
|
recursive,
|
|
1050
1254
|
warn=warn,
|
|
1051
1255
|
process=process,
|
|
1052
|
-
**kwargs
|
|
1256
|
+
**kwargs,
|
|
1257
|
+
)
|
|
1053
1258
|
|
|
1054
1259
|
|
|
1055
1260
|
# check if the all the prev nodes are processed
|
|
1056
1261
|
def is_ready_to_process(in_node, processed_nodes, strict=True, local=False):
|
|
1057
1262
|
if isinstance(in_node, TriccNodeSelectOption):
|
|
1058
1263
|
node = in_node.select
|
|
1059
|
-
elif (
|
|
1060
|
-
isinstance(in_node, (TriccNodeActivityStart, TriccNodeMainStart)) ):
|
|
1264
|
+
elif isinstance(in_node, (TriccNodeActivityStart, TriccNodeMainStart)):
|
|
1061
1265
|
# check before
|
|
1062
1266
|
return True
|
|
1063
1267
|
else:
|
|
1064
1268
|
node = in_node
|
|
1065
|
-
if hasattr(node,
|
|
1269
|
+
if hasattr(node, "prev_nodes"):
|
|
1066
1270
|
# ensure the previous node of the select are processed, not the option prev nodes
|
|
1067
1271
|
for prev_node in node.prev_nodes:
|
|
1068
1272
|
if is_prev_processed(prev_node, node, processed_nodes, local) is False:
|
|
1069
1273
|
return False
|
|
1070
1274
|
return True
|
|
1071
|
-
|
|
1275
|
+
|
|
1276
|
+
|
|
1072
1277
|
def is_prev_processed(prev_node, node, processed_nodes, local):
|
|
1073
|
-
if hasattr(prev_node,
|
|
1074
|
-
return
|
|
1278
|
+
if hasattr(prev_node, "select"):
|
|
1279
|
+
return is_prev_processed(prev_node.select, node, processed_nodes, local)
|
|
1075
1280
|
if prev_node not in processed_nodes and (not local):
|
|
1076
1281
|
if isinstance(prev_node, TriccNodeExclusive):
|
|
1077
1282
|
iterator = iter(prev_node.prev_nodes)
|
|
1078
1283
|
p_n_node = next(iterator)
|
|
1079
|
-
logger.debug(
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1284
|
+
logger.debug(
|
|
1285
|
+
"is_ready_to_process:failed:via_excl: {} - {} > {} {}:{}".format(
|
|
1286
|
+
get_data_for_log(p_n_node), prev_node.get_name(), node.__class__, node.get_name(), node.instance
|
|
1287
|
+
)
|
|
1288
|
+
)
|
|
1083
1289
|
|
|
1084
1290
|
else:
|
|
1085
|
-
logger.debug(
|
|
1086
|
-
|
|
1087
|
-
|
|
1291
|
+
logger.debug(
|
|
1292
|
+
"is_ready_to_process:failed: {} -> {} {}:{}".format(
|
|
1293
|
+
get_data_for_log(prev_node), node.__class__, node.get_name(), node.instance
|
|
1294
|
+
)
|
|
1295
|
+
)
|
|
1088
1296
|
|
|
1089
|
-
logger.debug(
|
|
1090
|
-
|
|
1091
|
-
|
|
1297
|
+
logger.debug(
|
|
1298
|
+
"prev node node {}:{} for node {} not in processed".format(
|
|
1299
|
+
prev_node.__class__, prev_node.get_name(), node.get_name()
|
|
1300
|
+
)
|
|
1301
|
+
)
|
|
1092
1302
|
return False
|
|
1093
1303
|
return True
|
|
1094
1304
|
|
|
1095
1305
|
|
|
1306
|
+
def print_trace(node, prev_node, processed_nodes, stashed_nodes, history=[]):
|
|
1096
1307
|
|
|
1097
|
-
def print_trace(node, prev_node, processed_nodes, stashed_nodes, history = []):
|
|
1098
|
-
|
|
1099
1308
|
if node != prev_node:
|
|
1100
1309
|
if node in processed_nodes:
|
|
1101
|
-
logger.warning(
|
|
1102
|
-
|
|
1103
|
-
|
|
1310
|
+
logger.warning(
|
|
1311
|
+
"print trace :: node {} was the last not processed ({}):{}".format(
|
|
1312
|
+
get_data_for_log(prev_node), node.id, ">".join(history)
|
|
1313
|
+
)
|
|
1314
|
+
)
|
|
1315
|
+
# processed_nodes.add(prev_node)
|
|
1104
1316
|
return False
|
|
1105
1317
|
elif node in history:
|
|
1106
|
-
logger.critical(
|
|
1107
|
-
|
|
1318
|
+
logger.critical(
|
|
1319
|
+
"print trace :: CYCLE node {} found in history ({})".format(
|
|
1320
|
+
get_data_for_log(prev_node), ">".join(history)
|
|
1321
|
+
)
|
|
1322
|
+
)
|
|
1108
1323
|
exit(1)
|
|
1109
1324
|
elif node in stashed_nodes:
|
|
1110
1325
|
# logger.debug("print trace :: node {}::{} in stashed".format(node.__class__,node.get_name()))
|
|
1111
1326
|
return False
|
|
1112
1327
|
# else:
|
|
1113
|
-
# logger.debug("print trace :: node {} not processed/stashed".format(node.get_name()))
|
|
1328
|
+
# logger.debug("print trace :: node {} not processed/stashed".format(node.get_name()))
|
|
1114
1329
|
return True
|
|
1115
1330
|
|
|
1116
1331
|
|
|
1117
|
-
def reverse_walkthrough(in_node, next_node, callback, processed_nodes, stashed_nodes, history
|
|
1332
|
+
def reverse_walkthrough(in_node, next_node, callback, processed_nodes, stashed_nodes, history=[]):
|
|
1118
1333
|
# transform dead-end nodes
|
|
1119
1334
|
if next_node == in_node and next_node not in stashed_nodes:
|
|
1120
1335
|
# workaround fir loop
|
|
1121
1336
|
return False
|
|
1122
|
-
|
|
1123
1337
|
|
|
1124
1338
|
if isinstance(in_node, TriccNodeSelectOption):
|
|
1125
1339
|
node = in_node.select
|
|
@@ -1132,53 +1346,79 @@ def reverse_walkthrough(in_node, next_node, callback, processed_nodes, stashed_n
|
|
|
1132
1346
|
if isinstance(in_node, TriccNodeActivity):
|
|
1133
1347
|
prev_nodes = set(in_node.get_end_nodes())
|
|
1134
1348
|
for prev in prev_nodes:
|
|
1135
|
-
reverse_walkthrough(
|
|
1136
|
-
|
|
1349
|
+
reverse_walkthrough(
|
|
1350
|
+
prev,
|
|
1351
|
+
next_node,
|
|
1352
|
+
callback,
|
|
1353
|
+
processed_nodes=processed_nodes,
|
|
1354
|
+
stashed_nodes=stashed_nodes,
|
|
1355
|
+
history=history,
|
|
1356
|
+
)
|
|
1357
|
+
if hasattr(node, "prev_nodes"):
|
|
1137
1358
|
if node.prev_nodes:
|
|
1138
1359
|
for prev in node.prev_nodes:
|
|
1139
|
-
reverse_walkthrough(
|
|
1360
|
+
reverse_walkthrough(
|
|
1361
|
+
prev,
|
|
1362
|
+
node,
|
|
1363
|
+
callback,
|
|
1364
|
+
processed_nodes=processed_nodes,
|
|
1365
|
+
stashed_nodes=stashed_nodes,
|
|
1366
|
+
history=history,
|
|
1367
|
+
)
|
|
1140
1368
|
elif node in node.activity.calculates:
|
|
1141
|
-
reverse_walkthrough(
|
|
1369
|
+
reverse_walkthrough(
|
|
1370
|
+
prev,
|
|
1371
|
+
node.activity.root,
|
|
1372
|
+
callback,
|
|
1373
|
+
processed_nodes=processed_nodes,
|
|
1374
|
+
stashed_nodes=stashed_nodes,
|
|
1375
|
+
history=history,
|
|
1376
|
+
)
|
|
1142
1377
|
|
|
1143
1378
|
if issubclass(node.__class__, TriccRhombusMixIn):
|
|
1144
1379
|
if isinstance(node.reference, list):
|
|
1145
1380
|
for ref in node.reference:
|
|
1146
|
-
reverse_walkthrough(
|
|
1147
|
-
|
|
1148
|
-
|
|
1381
|
+
reverse_walkthrough(
|
|
1382
|
+
ref,
|
|
1383
|
+
node,
|
|
1384
|
+
callback,
|
|
1385
|
+
processed_nodes=processed_nodes,
|
|
1386
|
+
stashed_nodes=stashed_nodes,
|
|
1387
|
+
history=history,
|
|
1388
|
+
)
|
|
1149
1389
|
|
|
1150
1390
|
|
|
1151
1391
|
def get_prev_node_by_name(processed_nodes, name, node):
|
|
1152
|
-
# look for the node in the same activity
|
|
1153
|
-
last_calc = get_last_version(
|
|
1154
|
-
name,
|
|
1155
|
-
processed_nodes
|
|
1156
|
-
)
|
|
1392
|
+
# look for the node in the same activity
|
|
1393
|
+
last_calc = get_last_version(name, processed_nodes)
|
|
1157
1394
|
if last_calc:
|
|
1158
1395
|
return last_calc
|
|
1159
|
-
|
|
1396
|
+
|
|
1160
1397
|
filtered = list(
|
|
1161
|
-
filter(
|
|
1162
|
-
hasattr(p_node,
|
|
1163
|
-
and p_node.name == name
|
|
1164
|
-
and p_node.instance == node.instance
|
|
1165
|
-
and p_node.path_len <= node.path_len,
|
|
1166
|
-
|
|
1398
|
+
filter(
|
|
1399
|
+
lambda p_node: hasattr(p_node, "name")
|
|
1400
|
+
and p_node.name == name
|
|
1401
|
+
and p_node.instance == node.instance
|
|
1402
|
+
and p_node.path_len <= node.path_len,
|
|
1403
|
+
processed_nodes,
|
|
1404
|
+
)
|
|
1405
|
+
)
|
|
1167
1406
|
if len(filtered) == 0:
|
|
1168
|
-
filtered = list(filter(lambda p_node: hasattr(p_node,
|
|
1407
|
+
filtered = list(filter(lambda p_node: hasattr(p_node, "name") and p_node.name == name, processed_nodes))
|
|
1169
1408
|
if len(filtered) > 0:
|
|
1170
1409
|
return sorted(filtered, key=lambda x: x.path_len, reverse=False)[0]
|
|
1171
1410
|
|
|
1411
|
+
|
|
1172
1412
|
MIN_LOOP_COUNT = 10
|
|
1173
1413
|
|
|
1414
|
+
|
|
1174
1415
|
def check_stashed_loop(stashed_nodes, prev_stashed_nodes, processed_nodes, len_prev_processed_nodes, loop_count):
|
|
1175
|
-
|
|
1176
|
-
|
|
1416
|
+
|
|
1177
1417
|
if len(stashed_nodes) == len(prev_stashed_nodes):
|
|
1178
|
-
# to avoid checking the details
|
|
1179
|
-
if loop_count<=0:
|
|
1418
|
+
# to avoid checking the details
|
|
1419
|
+
if loop_count <= 0:
|
|
1180
1420
|
if loop_count < -MIN_LOOP_COUNT:
|
|
1181
|
-
loop_count = MIN_LOOP_COUNT+1
|
|
1421
|
+
loop_count = MIN_LOOP_COUNT + 1
|
|
1182
1422
|
else:
|
|
1183
1423
|
loop_count -= 1
|
|
1184
1424
|
if loop_count > MIN_LOOP_COUNT:
|
|
@@ -1186,51 +1426,56 @@ def check_stashed_loop(stashed_nodes, prev_stashed_nodes, processed_nodes, len_p
|
|
|
1186
1426
|
loop_count += 1
|
|
1187
1427
|
if loop_count > max(MIN_LOOP_COUNT, 11 * len(prev_stashed_nodes) + 1):
|
|
1188
1428
|
logger.critical("Stashed node list was unchanged: loop likely or unresolved dependence")
|
|
1189
|
-
waited, looped =
|
|
1429
|
+
waited, looped = get_all_dependant(stashed_nodes, stashed_nodes, processed_nodes)
|
|
1190
1430
|
logger.debug(f"{len(looped)} nodes waiting stashed nodes")
|
|
1191
1431
|
logger.info("unresolved reference")
|
|
1192
1432
|
for es_node in [n for n in stashed_nodes if isinstance(n, TriccReference)]:
|
|
1193
|
-
logger.info(
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1433
|
+
logger.info(
|
|
1434
|
+
"Stashed node {}:{}|{} {}".format(
|
|
1435
|
+
es_node.activity.get_name() if hasattr(es_node, "activity") else "",
|
|
1436
|
+
es_node.activity.instance if hasattr(es_node, "activity") else "",
|
|
1437
|
+
es_node.__class__,
|
|
1438
|
+
es_node.get_name(),
|
|
1439
|
+
)
|
|
1440
|
+
)
|
|
1441
|
+
for es_node in [
|
|
1442
|
+
node for node_list in looped.values() for node in node_list if isinstance(node, TriccReference)
|
|
1443
|
+
]:
|
|
1444
|
+
logger.info(
|
|
1445
|
+
"looped node {}:{}|{} {}".format(
|
|
1446
|
+
es_node.activity.get_name() if hasattr(es_node, "activity") else "",
|
|
1447
|
+
es_node.activity.instance if hasattr(es_node, "activity") else "",
|
|
1448
|
+
es_node.__class__,
|
|
1449
|
+
es_node.get_name(),
|
|
1450
|
+
)
|
|
1451
|
+
)
|
|
1452
|
+
for es_node in [
|
|
1453
|
+
node for node_list in waited.values() for node in node_list if isinstance(node, TriccReference)
|
|
1454
|
+
]:
|
|
1455
|
+
logger.info(
|
|
1456
|
+
"waited node {}:{}|{} {}".format(
|
|
1457
|
+
es_node.activity.get_name() if hasattr(es_node, "activity") else "",
|
|
1458
|
+
es_node.activity.instance if hasattr(es_node, "activity") else "",
|
|
1459
|
+
es_node.__class__,
|
|
1460
|
+
es_node.get_name(),
|
|
1461
|
+
)
|
|
1462
|
+
)
|
|
1210
1463
|
logger.info("looped nodes")
|
|
1211
1464
|
for dep_list in looped:
|
|
1212
1465
|
for d in looped[dep_list]:
|
|
1213
1466
|
if str(d) in looped:
|
|
1214
|
-
logger.critical("[{}] depends on [{}]".format(
|
|
1215
|
-
dep_list, str(d)
|
|
1216
|
-
))
|
|
1467
|
+
logger.critical("[{}] depends on [{}]".format(dep_list, str(d)))
|
|
1217
1468
|
else:
|
|
1218
|
-
logger.error("[{}] depends on [{}]".format(
|
|
1219
|
-
dep_list, str(d)
|
|
1220
|
-
))
|
|
1469
|
+
logger.error("[{}] depends on [{}]".format(dep_list, str(d)))
|
|
1221
1470
|
if dep_list in waited:
|
|
1222
1471
|
for d in waited[dep_list]:
|
|
1223
|
-
logger.warning("[{}] depends on [{}]".format(
|
|
1224
|
-
dep_list, str(d)
|
|
1225
|
-
))
|
|
1472
|
+
logger.warning("[{}] depends on [{}]".format(dep_list, str(d)))
|
|
1226
1473
|
logger.info("waited nodes")
|
|
1227
1474
|
for dep_list in waited:
|
|
1228
1475
|
if dep_list not in looped:
|
|
1229
1476
|
for d in waited[dep_list]:
|
|
1230
|
-
logger.warning("[{}] depends on [{}]".format(
|
|
1231
|
-
|
|
1232
|
-
))
|
|
1233
|
-
|
|
1477
|
+
logger.warning("[{}] depends on [{}]".format(dep_list, d.get_name()))
|
|
1478
|
+
|
|
1234
1479
|
if len(stashed_nodes) == len(prev_stashed_nodes):
|
|
1235
1480
|
exit(1)
|
|
1236
1481
|
else:
|
|
@@ -1239,6 +1484,7 @@ def check_stashed_loop(stashed_nodes, prev_stashed_nodes, processed_nodes, len_p
|
|
|
1239
1484
|
loop_count = 0
|
|
1240
1485
|
return loop_count
|
|
1241
1486
|
|
|
1487
|
+
|
|
1242
1488
|
def add_to_tree(tree, n, d):
|
|
1243
1489
|
n_str = str(n)
|
|
1244
1490
|
if n_str not in tree:
|
|
@@ -1247,10 +1493,10 @@ def add_to_tree(tree, n, d):
|
|
|
1247
1493
|
tree[n_str].append(d)
|
|
1248
1494
|
return tree
|
|
1249
1495
|
|
|
1250
|
-
|
|
1251
|
-
def get_all_dependant(loop, stashed_nodes, processed_nodes, depth=0, waited=None
|
|
1496
|
+
|
|
1497
|
+
def get_all_dependant(loop, stashed_nodes, processed_nodes, depth=0, waited=None, looped=None, path=None):
|
|
1252
1498
|
if path is None:
|
|
1253
|
-
path =[]
|
|
1499
|
+
path = []
|
|
1254
1500
|
if looped is None:
|
|
1255
1501
|
looped = {}
|
|
1256
1502
|
if waited is None:
|
|
@@ -1260,50 +1506,55 @@ def get_all_dependant(loop, stashed_nodes, processed_nodes, depth=0, waited=None
|
|
|
1260
1506
|
cur_path = path.copy()
|
|
1261
1507
|
cur_path.append(n)
|
|
1262
1508
|
dependant = OrderedSet()
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
dependant = dependant | n.prev_nodes
|
|
1268
|
-
if hasattr(n, 'get_references'):
|
|
1269
|
-
dependant = dependant | (n.get_references() or OrderedSet())
|
|
1509
|
+
if hasattr(n, "prev_nodes") and n.prev_nodes:
|
|
1510
|
+
dependant = dependant | n.prev_nodes
|
|
1511
|
+
if hasattr(n, "get_references"):
|
|
1512
|
+
dependant = dependant | (n.get_references() or OrderedSet())
|
|
1270
1513
|
if not isinstance(dependant, list):
|
|
1271
1514
|
pass
|
|
1272
1515
|
for d in dependant:
|
|
1273
1516
|
if d in path:
|
|
1274
|
-
logger.warning(
|
|
1517
|
+
logger.warning(
|
|
1518
|
+
f"loop {str(d)} already in path {'::'.join(map(str, path))} "
|
|
1519
|
+
)
|
|
1275
1520
|
if isinstance(d, TriccNodeSelectOption):
|
|
1276
1521
|
d = d.select
|
|
1277
|
-
|
|
1522
|
+
|
|
1278
1523
|
if isinstance(d, TriccReference):
|
|
1279
1524
|
if not any(n.name == d.value for n in processed_nodes):
|
|
1280
1525
|
if not any(n.name == d.value for n in stashed_nodes):
|
|
1281
1526
|
waited = add_to_tree(waited, n, d)
|
|
1282
|
-
else
|
|
1527
|
+
else:
|
|
1283
1528
|
looped = add_to_tree(looped, n, d)
|
|
1284
|
-
|
|
1529
|
+
|
|
1285
1530
|
elif d not in processed_nodes:
|
|
1286
1531
|
if d in stashed_nodes:
|
|
1287
1532
|
looped = add_to_tree(looped, n, d)
|
|
1288
|
-
else
|
|
1533
|
+
else:
|
|
1289
1534
|
waited = add_to_tree(waited, n, d)
|
|
1290
1535
|
all_dependant = all_dependant.union(dependant)
|
|
1291
1536
|
if depth < MAX_DRILL:
|
|
1292
|
-
waited, looped =
|
|
1293
|
-
|
|
1537
|
+
waited, looped = get_all_dependant(
|
|
1538
|
+
all_dependant, stashed_nodes, processed_nodes, depth + 1, waited, looped, path=cur_path
|
|
1539
|
+
)
|
|
1540
|
+
|
|
1294
1541
|
return waited, looped
|
|
1295
1542
|
|
|
1296
1543
|
|
|
1297
1544
|
MAX_DRILL = 3
|
|
1298
1545
|
|
|
1546
|
+
|
|
1299
1547
|
def get_last_end_node(processed_nodes, process=None):
|
|
1300
|
-
end_name =
|
|
1548
|
+
end_name = "tricc_end_"
|
|
1301
1549
|
if process:
|
|
1302
1550
|
end_name += process
|
|
1303
1551
|
return get_last_version(end_name, processed_nodes)
|
|
1304
1552
|
|
|
1553
|
+
|
|
1305
1554
|
# Set the source next node to target and clean next nodes of replace node
|
|
1306
|
-
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
def set_prev_next_node(source_node, target_node, replaced_node=None, edge_only=False, activity=None):
|
|
1307
1558
|
activity = activity or source_node.activity
|
|
1308
1559
|
source_id, source_node = get_node_from_id(activity, source_node, edge_only)
|
|
1309
1560
|
target_id, target_node = get_node_from_id(activity, target_node, edge_only)
|
|
@@ -1311,36 +1562,39 @@ def set_prev_next_node(source_node, target_node, replaced_node=None, edge_only =
|
|
|
1311
1562
|
if not edge_only:
|
|
1312
1563
|
set_prev_node(source_node, target_node, replaced_node, edge_only)
|
|
1313
1564
|
set_next_node(source_node, target_node, replaced_node, edge_only)
|
|
1314
|
-
|
|
1315
|
-
if activity and not any([(e.source == source_id) and (
|
|
1565
|
+
|
|
1566
|
+
if activity and not any([(e.source == source_id) and (e.target == target_id) for e in activity.edges]):
|
|
1316
1567
|
label = "continue" if issubclass(source_node.__class__, TriccNodeSelect) else None
|
|
1317
|
-
activity.edges.append(TriccEdge(id
|
|
1568
|
+
activity.edges.append(TriccEdge(id=generate_id(), source=source_id, target=target_id, value=label))
|
|
1569
|
+
|
|
1318
1570
|
|
|
1319
1571
|
def remove_prev_next(prev_node, next_node, activity=None):
|
|
1320
1572
|
activity = activity or prev_node.activity
|
|
1321
|
-
if hasattr(prev_node,
|
|
1573
|
+
if hasattr(prev_node, "next_nodes") and next_node in prev_node.next_nodes:
|
|
1322
1574
|
prev_node.next_nodes.remove(next_node)
|
|
1323
|
-
if hasattr(next_node,
|
|
1575
|
+
if hasattr(next_node, "prev_nodes") and prev_node in next_node.prev_nodes:
|
|
1324
1576
|
next_node.prev_nodes.remove(prev_node)
|
|
1325
|
-
|
|
1577
|
+
|
|
1326
1578
|
for e in list(activity.edges):
|
|
1327
|
-
if
|
|
1579
|
+
if e.target == getattr(next_node, "id", next_node) and e.source == getattr(prev_node, "id", prev_node):
|
|
1328
1580
|
activity.edges.remove(e)
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
def set_next_node(source_node, target_node, replaced_node=None, edge_only = False, activity=None):
|
|
1581
|
+
|
|
1582
|
+
|
|
1583
|
+
def set_next_node(source_node, target_node, replaced_node=None, edge_only=False, activity=None):
|
|
1333
1584
|
activity = activity or source_node.activity
|
|
1334
1585
|
replace_target = None
|
|
1335
|
-
if not edge_only:
|
|
1336
|
-
if replaced_node is not None and hasattr(source_node,
|
|
1586
|
+
if not edge_only:
|
|
1587
|
+
if replaced_node is not None and hasattr(source_node, "path") and replaced_node == source_node.path:
|
|
1337
1588
|
source_node.path = target_node
|
|
1338
|
-
elif
|
|
1589
|
+
elif (
|
|
1590
|
+
replaced_node is not None and hasattr(source_node, "next_nodes") and replaced_node in source_node.next_nodes
|
|
1591
|
+
):
|
|
1339
1592
|
replace_target = True
|
|
1340
1593
|
source_node.next_nodes.remove(replaced_node)
|
|
1341
|
-
if hasattr(replaced_node,
|
|
1594
|
+
if hasattr(replaced_node, "prev_nodes") and source_node in replaced_node.prev_nodes:
|
|
1342
1595
|
replaced_node.prev_nodes.remove(source_node)
|
|
1343
|
-
#if replaced_node is not None and hasattr(target_node, 'next_nodes')
|
|
1596
|
+
# if replaced_node is not None and hasattr(target_node, 'next_nodes')
|
|
1597
|
+
# and replaced_node in target_node.next_nodes:
|
|
1344
1598
|
# target_node.next_nodes.remove(replaced_node)
|
|
1345
1599
|
if target_node not in source_node.next_nodes:
|
|
1346
1600
|
source_node.next_nodes.add(target_node)
|
|
@@ -1359,31 +1613,34 @@ def set_next_node(source_node, target_node, replaced_node=None, edge_only = Fals
|
|
|
1359
1613
|
if replaced_node and replace_target:
|
|
1360
1614
|
if replaced_node.id in replaced_node.activity.nodes:
|
|
1361
1615
|
del replaced_node.activity.nodes[replaced_node.id]
|
|
1362
|
-
next_edges = set(
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1616
|
+
next_edges = set(
|
|
1617
|
+
[
|
|
1618
|
+
e for e in replaced_node.activity.edges
|
|
1619
|
+
if (e.target == replaced_node.id or e.target == replaced_node)
|
|
1620
|
+
] + [
|
|
1621
|
+
e for e in activity.edges
|
|
1622
|
+
if (e.target == replaced_node.id or e.target == replaced_node)
|
|
1623
|
+
]
|
|
1624
|
+
)
|
|
1625
|
+
if len(next_edges) == 0:
|
|
1626
|
+
for e in next_edges:
|
|
1369
1627
|
e.target = target_node.id
|
|
1370
1628
|
|
|
1371
|
-
|
|
1372
1629
|
|
|
1373
1630
|
# Set the target_node prev node to source and clean prev nodes of replace_node
|
|
1374
|
-
def set_prev_node(source_node, target_node, replaced_node=None, edge_only
|
|
1631
|
+
def set_prev_node(source_node, target_node, replaced_node=None, edge_only=False, activity=None):
|
|
1375
1632
|
activity = activity or source_node.activity
|
|
1376
1633
|
replace_source = False
|
|
1377
1634
|
# update the prev node of the target not if not an end node
|
|
1378
1635
|
# update directly the prev node of the target
|
|
1379
|
-
if replaced_node is not None and hasattr(target_node,
|
|
1636
|
+
if replaced_node is not None and hasattr(target_node, "path") and replaced_node == target_node.path:
|
|
1380
1637
|
target_node.path = source_node
|
|
1381
|
-
if replaced_node is not None and hasattr(target_node,
|
|
1638
|
+
if replaced_node is not None and hasattr(target_node, "prev_nodes") and replaced_node in target_node.prev_nodes:
|
|
1382
1639
|
replace_source = True
|
|
1383
1640
|
target_node.prev_nodes.remove(replaced_node)
|
|
1384
|
-
if hasattr(replaced_node,
|
|
1641
|
+
if hasattr(replaced_node, "next_nodes") and source_node in replaced_node.next_nodes:
|
|
1385
1642
|
replaced_node.next_nodes.remove(source_node)
|
|
1386
|
-
#if replaced_node is not None and hasattr(source_node, 'prev_nodes') and replaced_node in source_node.prev_nodes:
|
|
1643
|
+
# if replaced_node is not None and hasattr(source_node, 'prev_nodes') and replaced_node in source_node.prev_nodes:
|
|
1387
1644
|
# source_node.prev_nodes.remove(replaced_node)
|
|
1388
1645
|
if source_node not in target_node.prev_nodes:
|
|
1389
1646
|
target_node.prev_nodes.add(source_node)
|
|
@@ -1391,18 +1648,17 @@ def set_prev_node(source_node, target_node, replaced_node=None, edge_only = Fals
|
|
|
1391
1648
|
activity.nodes[source_node.id] = source_node
|
|
1392
1649
|
if replaced_node and replace_source:
|
|
1393
1650
|
if replaced_node.id in replaced_node.activity.nodes:
|
|
1394
|
-
|
|
1395
|
-
next_edges = set(
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
for e in next_edges:
|
|
1651
|
+
del replaced_node.activity.nodes[replaced_node.id]
|
|
1652
|
+
next_edges = set(
|
|
1653
|
+
[e for e in replaced_node.activity.edges if (e.source == replaced_node.id or e.source == replaced_node)]
|
|
1654
|
+
+ [e for e in activity.edges if (e.source == replaced_node.id or e.source == replaced_node)]
|
|
1655
|
+
)
|
|
1656
|
+
if len(next_edges) == 0:
|
|
1657
|
+
for e in next_edges:
|
|
1402
1658
|
e.target = target_node.id
|
|
1403
|
-
|
|
1404
1659
|
|
|
1405
|
-
|
|
1660
|
+
|
|
1661
|
+
def replace_node(old, new, page=None):
|
|
1406
1662
|
if page is None:
|
|
1407
1663
|
page = old.activity
|
|
1408
1664
|
logger.debug("replacing node {} with node {} from page {}".format(old.get_name(), new.get_name(), page.get_name()))
|
|
@@ -1429,23 +1685,25 @@ def replace_node(old, new, page = None):
|
|
|
1429
1685
|
if edge.target == old.id:
|
|
1430
1686
|
edge.target = new.id
|
|
1431
1687
|
|
|
1432
|
-
|
|
1688
|
+
|
|
1689
|
+
def replace_prev_next_node(prev_node, next_node, old_node, force=False):
|
|
1433
1690
|
replace_prev_node(prev_node, next_node, old_node)
|
|
1434
1691
|
replace_next_node(prev_node, next_node, old_node)
|
|
1435
1692
|
|
|
1436
|
-
|
|
1437
|
-
|
|
1693
|
+
|
|
1694
|
+
def replace_prev_node(prev_node, next_node, old_node, force=False):
|
|
1695
|
+
# create a copy pf the list
|
|
1438
1696
|
list_nodes = list(next_node.prev_nodes)
|
|
1439
1697
|
# replace in case old node is found
|
|
1440
1698
|
for p_n_node in list_nodes:
|
|
1441
1699
|
if p_n_node == old_node or force:
|
|
1442
1700
|
set_prev_next_node(prev_node, next_node, old_node)
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
def replace_next_node(prev_node,next_node,old_node):
|
|
1701
|
+
|
|
1702
|
+
|
|
1703
|
+
def replace_next_node(prev_node, next_node, old_node):
|
|
1446
1704
|
list_nodes = list(prev_node.next_nodes)
|
|
1447
1705
|
for n_p_node in list_nodes:
|
|
1448
|
-
if n_p_node == old_node
|
|
1706
|
+
if n_p_node == old_node:
|
|
1449
1707
|
set_prev_next_node(prev_node, next_node, old_node)
|
|
1450
1708
|
|
|
1451
1709
|
|
|
@@ -1458,6 +1716,7 @@ ACTIVE_ACTIVITY_LOWER_PRIORITY = 3000
|
|
|
1458
1716
|
RHOMBUS_PRIORITY = 1000
|
|
1459
1717
|
DEFAULT_PRIORITY = 2000
|
|
1460
1718
|
|
|
1719
|
+
|
|
1461
1720
|
def reorder_node_list(node_list, group, processed_nodes):
|
|
1462
1721
|
# Cache active activities for O(1) lookup
|
|
1463
1722
|
active_activities = {n.activity for n in processed_nodes}
|
|
@@ -1493,49 +1752,51 @@ def reorder_node_list(node_list, group, processed_nodes):
|
|
|
1493
1752
|
|
|
1494
1753
|
# Sort in place, highest priority first
|
|
1495
1754
|
node_list.sort(key=get_priority, reverse=True)
|
|
1496
|
-
|
|
1755
|
+
|
|
1756
|
+
|
|
1497
1757
|
def loop_info(loop, **kwargs):
|
|
1498
1758
|
logger.critical("dependency details")
|
|
1499
1759
|
for n in loop:
|
|
1500
|
-
i=0
|
|
1760
|
+
i = 0
|
|
1501
1761
|
logger.critical(f"{i}: {n.__class__}::{n.get_name()}")
|
|
1502
1762
|
i += 1
|
|
1503
1763
|
|
|
1504
1764
|
|
|
1505
|
-
def has_loop(
|
|
1765
|
+
def has_loop(
|
|
1766
|
+
node, processed_nodes, stashed_nodes, warn, node_path=[], action_on_loop=loop_info, action_on_other=None, **kwargs
|
|
1767
|
+
):
|
|
1506
1768
|
next_nodes = get_extended_next_nodes(node)
|
|
1507
|
-
for next_node in next_nodes:
|
|
1769
|
+
for next_node in next_nodes:
|
|
1508
1770
|
if next_node in node_path:
|
|
1509
1771
|
loop_start_key = node_path.index(next_node)
|
|
1510
1772
|
loop = node_path[loop_start_key:]
|
|
1511
1773
|
loop.append(node)
|
|
1512
1774
|
loop.append(next_node)
|
|
1513
1775
|
action_on_loop(loop, **kwargs)
|
|
1514
|
-
return False
|
|
1776
|
+
return False
|
|
1515
1777
|
if callable(action_on_other):
|
|
1516
1778
|
action_on_other(next_node, **kwargs)
|
|
1517
1779
|
return True
|
|
1518
|
-
|
|
1519
|
-
|
|
1780
|
+
|
|
1520
1781
|
|
|
1521
1782
|
def get_extended_next_nodes(node):
|
|
1522
|
-
|
|
1523
|
-
nodes =
|
|
1524
|
-
if issubclass(node.__class__, TriccNodeSelect
|
|
1783
|
+
|
|
1784
|
+
nodes = node.next_nodes if hasattr(node, "next_nodes") else set()
|
|
1785
|
+
if issubclass(node.__class__, TriccNodeSelect):
|
|
1525
1786
|
for o in node.options.values():
|
|
1526
1787
|
nodes = nodes | o.next_nodes
|
|
1527
|
-
if isinstance(node, (
|
|
1788
|
+
if isinstance(node, (TriccNodeActivity)):
|
|
1528
1789
|
nodes = nodes | node.root.next_nodes
|
|
1529
1790
|
return nodes
|
|
1530
|
-
|
|
1791
|
+
|
|
1531
1792
|
|
|
1532
1793
|
# calculate or retrieve a node expression
|
|
1533
|
-
def get_node_expression(
|
|
1794
|
+
def get_node_expression(in_node, processed_nodes, get_overall_exp=False, is_prev=False, negate=False, process=None):
|
|
1534
1795
|
# in case of calculate we only use the select multiple if none is not selected
|
|
1535
1796
|
expression = None
|
|
1536
1797
|
negate_expression = None
|
|
1537
1798
|
node = in_node
|
|
1538
|
-
if isinstance(node, (TriccNodeActivityStart,TriccNodeMainStart)):
|
|
1799
|
+
if isinstance(node, (TriccNodeActivityStart, TriccNodeMainStart)):
|
|
1539
1800
|
if is_prev and get_overall_exp:
|
|
1540
1801
|
expression = get_node_expression(
|
|
1541
1802
|
node.activity,
|
|
@@ -1543,13 +1804,13 @@ def get_node_expression( in_node, processed_nodes, get_overall_exp=False, is_pre
|
|
|
1543
1804
|
get_overall_exp=True,
|
|
1544
1805
|
is_prev=is_prev,
|
|
1545
1806
|
negate=negate,
|
|
1546
|
-
process=process
|
|
1807
|
+
process=process,
|
|
1547
1808
|
)
|
|
1548
1809
|
if isinstance(node, TriccNodeMainStart):
|
|
1549
|
-
expression =
|
|
1810
|
+
expression = get_applicability_expression(node.activity, processed_nodes, process, expression)
|
|
1550
1811
|
elif isinstance(node, (TriccNodeActivityStart)):
|
|
1551
1812
|
return TriccStatic(True)
|
|
1552
|
-
|
|
1813
|
+
|
|
1553
1814
|
elif isinstance(node, TriccNodeWait):
|
|
1554
1815
|
if is_prev:
|
|
1555
1816
|
# the wait don't do any calculation with the reference it is only use to wait until the reference are valid
|
|
@@ -1558,86 +1819,78 @@ def get_node_expression( in_node, processed_nodes, get_overall_exp=False, is_pre
|
|
|
1558
1819
|
processed_nodes=processed_nodes,
|
|
1559
1820
|
get_overall_exp=get_overall_exp,
|
|
1560
1821
|
is_prev=True,
|
|
1561
|
-
process=process
|
|
1562
|
-
|
|
1822
|
+
process=process,
|
|
1823
|
+
)
|
|
1563
1824
|
else:
|
|
1564
|
-
#it is a empty calculate
|
|
1825
|
+
# it is a empty calculate
|
|
1565
1826
|
return None
|
|
1566
1827
|
elif isinstance(node, TriccNodeRhombus):
|
|
1567
|
-
|
|
1568
|
-
# expression = TriccOperation(
|
|
1569
|
-
# TriccOperator.ISTRUE,
|
|
1570
|
-
# [node]
|
|
1571
|
-
# )
|
|
1572
|
-
# else:
|
|
1573
|
-
expression = get_rhombus_terms(node, processed_nodes, process=process) # if issubclass(node.__class__, TricNodeDisplayCalulate) else TRICC_CALC_EXPRESSION.format(get_export_name(node)) #
|
|
1828
|
+
expression = get_rhombus_terms(node, processed_nodes, process=process)
|
|
1574
1829
|
negate_expression = not_clean(expression)
|
|
1575
|
-
if node.path is None
|
|
1830
|
+
if node.path is None:
|
|
1576
1831
|
if len(node.prev_nodes) == 1:
|
|
1577
1832
|
node.path = list(node.prev_nodes)[0]
|
|
1578
1833
|
elif len(node.prev_nodes) > 1:
|
|
1579
1834
|
logger.critical(f"missing path for Rhombus {node.get_name()}")
|
|
1580
1835
|
exit(1)
|
|
1581
1836
|
prev_exp = get_node_expression(
|
|
1582
|
-
node.path,
|
|
1583
|
-
|
|
1584
|
-
get_overall_exp=get_overall_exp,
|
|
1585
|
-
is_prev=True,
|
|
1586
|
-
process=process)
|
|
1837
|
+
node.path, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, is_prev=True, process=process
|
|
1838
|
+
)
|
|
1587
1839
|
if prev_exp and expression:
|
|
1588
1840
|
expression = and_join([prev_exp, expression])
|
|
1589
|
-
negate_expression = and_join([
|
|
1590
|
-
prev_exp,
|
|
1591
|
-
negate_expression
|
|
1592
|
-
])
|
|
1841
|
+
negate_expression = and_join([prev_exp, negate_expression])
|
|
1593
1842
|
|
|
1594
1843
|
elif prev_exp:
|
|
1595
|
-
|
|
1844
|
+
|
|
1596
1845
|
logger.error(f"useless rhombus {node.get_name()}")
|
|
1597
1846
|
expression = prev_exp
|
|
1598
1847
|
negate_expression = prev_exp
|
|
1599
1848
|
logger.critical(f"Rhombus without expression {node.get_name()}")
|
|
1600
1849
|
elif is_prev and issubclass(node.__class__, TriccNodeDisplayCalculateBase):
|
|
1601
1850
|
expression = TriccOperation(TriccOperator.ISTRUE, [node])
|
|
1602
|
-
elif hasattr(node,
|
|
1851
|
+
elif hasattr(node, "expression_reference") and isinstance(node.expression_reference, TriccOperation):
|
|
1603
1852
|
# if issubclass(node.__class__, TriccNodeDisplayCalculateBase):
|
|
1604
1853
|
# expression = TriccOperation(
|
|
1605
1854
|
# TriccOperator.CAST_NUMBER,
|
|
1606
1855
|
# [node.expression_reference])
|
|
1607
|
-
# else:
|
|
1608
|
-
expression = node.expression_reference
|
|
1856
|
+
# else:
|
|
1857
|
+
expression = node.expression_reference
|
|
1609
1858
|
elif is_prev and isinstance(node, TriccNodeSelectOption):
|
|
1610
1859
|
if negate:
|
|
1611
1860
|
negate_expression = get_selected_option_expression(node, negate)
|
|
1612
1861
|
else:
|
|
1613
1862
|
expression = get_selected_option_expression(node, negate)
|
|
1614
|
-
#TODO remove that and manage it on the "Save" part
|
|
1863
|
+
# TODO remove that and manage it on the "Save" part
|
|
1615
1864
|
elif is_prev and isinstance(node, TriccNodeSelectNotAvailable):
|
|
1616
|
-
expression =
|
|
1617
|
-
TriccOperator.SELECTED,
|
|
1618
|
-
[
|
|
1619
|
-
node,
|
|
1620
|
-
TriccStatic(1)
|
|
1621
|
-
]
|
|
1622
|
-
)
|
|
1865
|
+
expression = TriccOperation(TriccOperator.SELECTED, [node, TriccStatic(1)])
|
|
1623
1866
|
elif issubclass(node.__class__, TriccNodeCalculateBase):
|
|
1624
1867
|
if negate:
|
|
1625
|
-
negate_expression = get_calculation_terms(
|
|
1868
|
+
negate_expression = get_calculation_terms(
|
|
1869
|
+
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, negate=True, process=process
|
|
1870
|
+
)
|
|
1626
1871
|
else:
|
|
1627
|
-
expression = get_calculation_terms(
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
elif
|
|
1872
|
+
expression = get_calculation_terms(
|
|
1873
|
+
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, process=process
|
|
1874
|
+
)
|
|
1875
|
+
|
|
1876
|
+
elif (
|
|
1877
|
+
(not is_prev or not ONE_QUESTION_AT_A_TIME)
|
|
1878
|
+
and hasattr(node, "relevance")
|
|
1879
|
+
and isinstance(node.relevance, (TriccOperation, TriccStatic))
|
|
1880
|
+
):
|
|
1881
|
+
expression = node.relevance
|
|
1882
|
+
elif ONE_QUESTION_AT_A_TIME and is_prev and not get_overall_exp and hasattr(node, "required") and node.required:
|
|
1632
1883
|
expression = get_required_node_expression(node)
|
|
1633
|
-
|
|
1884
|
+
|
|
1634
1885
|
if expression is None:
|
|
1635
|
-
expression = get_prev_node_expression(
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
#
|
|
1639
|
-
|
|
1640
|
-
|
|
1886
|
+
expression = get_prev_node_expression(
|
|
1887
|
+
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, process=process
|
|
1888
|
+
)
|
|
1889
|
+
# in_node not in processed_nodes is need for calculates that can but run after the end of the activity
|
|
1890
|
+
# if isinstance(node, TriccNodeActivitiy) and not prev:
|
|
1891
|
+
# expression = get_applicability_expression(node, processed_nodes, process, expression)
|
|
1892
|
+
# expression = get_prev_instance_skip_expression(node, processed_nodes, process, expression)
|
|
1893
|
+
# expression = get_process_skip_expression(node, processed_nodes, process, expression)
|
|
1641
1894
|
if negate:
|
|
1642
1895
|
if negate_expression is not None:
|
|
1643
1896
|
return negate_expression
|
|
@@ -1648,64 +1901,50 @@ def get_node_expression( in_node, processed_nodes, get_overall_exp=False, is_pre
|
|
|
1648
1901
|
# exit(1)
|
|
1649
1902
|
else:
|
|
1650
1903
|
return expression
|
|
1651
|
-
|
|
1904
|
+
|
|
1905
|
+
|
|
1652
1906
|
def get_applicability_expression(node, processed_nodes, process, expression=None):
|
|
1653
|
-
if isinstance(node.applicability,(TriccStatic,TriccOperation, TriccReference)):
|
|
1907
|
+
if isinstance(node.applicability, (TriccStatic, TriccOperation, TriccReference)):
|
|
1654
1908
|
if expression:
|
|
1655
1909
|
expression = and_join([node.applicability, expression])
|
|
1656
1910
|
else:
|
|
1657
1911
|
expression = node.applicability
|
|
1658
|
-
|
|
1912
|
+
|
|
1659
1913
|
return expression
|
|
1660
|
-
|
|
1661
1914
|
|
|
1662
1915
|
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
1916
|
def get_prev_instance_skip_expression(node, processed_nodes, process, expression=None):
|
|
1666
1917
|
if node.base_instance is not None:
|
|
1667
|
-
activity = node
|
|
1668
1918
|
expression_inputs = []
|
|
1669
|
-
past_instances = [
|
|
1670
|
-
n for n in processed_nodes if getattr(n.base_instance, 'id', None) == node.base_instance.id
|
|
1671
|
-
]
|
|
1919
|
+
past_instances = [n for n in processed_nodes if getattr(n.base_instance, "id", None) == node.base_instance.id]
|
|
1672
1920
|
for past_instance in past_instances:
|
|
1673
1921
|
add_sub_expression(
|
|
1674
|
-
expression_inputs,
|
|
1922
|
+
expression_inputs,
|
|
1675
1923
|
get_node_expression(
|
|
1676
|
-
past_instance,
|
|
1677
|
-
|
|
1678
|
-
get_overall_exp=True,
|
|
1679
|
-
is_prev=True,
|
|
1680
|
-
process=process
|
|
1681
|
-
)
|
|
1924
|
+
past_instance, processed_nodes=processed_nodes, get_overall_exp=True, is_prev=True, process=process
|
|
1925
|
+
),
|
|
1682
1926
|
)
|
|
1683
1927
|
if expression and expression_inputs:
|
|
1684
1928
|
add_sub_expression(expression_inputs, expression)
|
|
1685
1929
|
expression = nand_join(expression, or_join(expression_inputs))
|
|
1686
1930
|
elif expression_inputs:
|
|
1687
|
-
expression =
|
|
1931
|
+
expression = negate_term(or_join(expression_inputs))
|
|
1688
1932
|
return expression
|
|
1689
1933
|
|
|
1690
1934
|
|
|
1691
1935
|
# end def
|
|
1692
1936
|
def get_process_skip_expression(node, processed_nodes, process, expression=None):
|
|
1693
|
-
list_ends = OrderedSet(
|
|
1694
|
-
filter(
|
|
1695
|
-
lambda x: issubclass(x.__class__, TriccNodeEnd),
|
|
1696
|
-
processed_nodes
|
|
1697
|
-
)
|
|
1698
|
-
)
|
|
1937
|
+
list_ends = OrderedSet(filter(lambda x: issubclass(x.__class__, TriccNodeEnd), processed_nodes))
|
|
1699
1938
|
if list_ends:
|
|
1700
1939
|
end_expressions = []
|
|
1701
1940
|
f_end_expression = get_end_expression(list_ends)
|
|
1702
1941
|
if f_end_expression:
|
|
1703
1942
|
end_expressions.append(f_end_expression)
|
|
1704
|
-
b_end_expression = get_end_expression(list_ends,
|
|
1943
|
+
b_end_expression = get_end_expression(list_ends, "pause")
|
|
1705
1944
|
if b_end_expression:
|
|
1706
|
-
end_expressions.append(b_end_expression)
|
|
1945
|
+
end_expressions.append(b_end_expression)
|
|
1707
1946
|
if process[0] in PROCESSES:
|
|
1708
|
-
for p in PROCESSES[PROCESSES.index(process[0])+1:]:
|
|
1947
|
+
for p in PROCESSES[PROCESSES.index(process[0]) + 1:]:
|
|
1709
1948
|
p_end_expression = get_end_expression(list_ends, p)
|
|
1710
1949
|
if p_end_expression:
|
|
1711
1950
|
end_expressions.append(p_end_expression)
|
|
@@ -1717,16 +1956,12 @@ def get_process_skip_expression(node, processed_nodes, process, expression=None)
|
|
|
1717
1956
|
else:
|
|
1718
1957
|
expression = and_join(end_expressions)
|
|
1719
1958
|
return expression
|
|
1720
|
-
|
|
1959
|
+
|
|
1960
|
+
|
|
1721
1961
|
def get_end_expression(processed_nodes, process=None):
|
|
1722
1962
|
end_node = get_last_end_node(processed_nodes, process)
|
|
1723
1963
|
if end_node:
|
|
1724
|
-
return TriccOperation(
|
|
1725
|
-
TriccOperator.ISNOTTRUE,
|
|
1726
|
-
[end_node]
|
|
1727
|
-
)
|
|
1728
|
-
|
|
1729
|
-
|
|
1964
|
+
return TriccOperation(TriccOperator.ISNOTTRUE, [end_node])
|
|
1730
1965
|
|
|
1731
1966
|
|
|
1732
1967
|
def export_proposed_diags(activity, diags=None, **kwargs):
|
|
@@ -1736,11 +1971,10 @@ def export_proposed_diags(activity, diags=None, **kwargs):
|
|
|
1736
1971
|
if isinstance(node, TriccNodeActivity):
|
|
1737
1972
|
diags = export_proposed_diags(node, diags, **kwargs)
|
|
1738
1973
|
if isinstance(node, TriccNodeProposedDiagnosis):
|
|
1739
|
-
if node.last is not False
|
|
1740
|
-
|
|
1741
|
-
diags.append(node)
|
|
1974
|
+
if node.last is not False and not any([diag.name == node.name for diag in diags]):
|
|
1975
|
+
diags.append(node)
|
|
1742
1976
|
return diags
|
|
1743
|
-
|
|
1977
|
+
|
|
1744
1978
|
|
|
1745
1979
|
def get_accept_diagnostic_node(code, display, severity, priority, activity):
|
|
1746
1980
|
node = TriccNodeAcceptDiagnostic(
|
|
@@ -1751,11 +1985,12 @@ def get_accept_diagnostic_node(code, display, severity, priority, activity):
|
|
|
1751
1985
|
activity=activity,
|
|
1752
1986
|
group=activity,
|
|
1753
1987
|
severity=severity,
|
|
1754
|
-
priority=priority
|
|
1988
|
+
priority=priority,
|
|
1755
1989
|
)
|
|
1756
1990
|
node.options = get_select_accept_reject_options(node, node.activity)
|
|
1757
1991
|
return node
|
|
1758
1992
|
|
|
1993
|
+
|
|
1759
1994
|
def get_diagnostic_node(code, display, severity, priority, activity):
|
|
1760
1995
|
node = TriccNodeCalculate(
|
|
1761
1996
|
id=generate_id("final." + code),
|
|
@@ -1764,51 +1999,48 @@ def get_diagnostic_node(code, display, severity, priority, activity):
|
|
|
1764
1999
|
activity=activity,
|
|
1765
2000
|
group=activity,
|
|
1766
2001
|
priority=priority,
|
|
1767
|
-
expression_reference=or_join(
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
TriccOperator.SELECTED,
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
])
|
|
2002
|
+
expression_reference=or_join(
|
|
2003
|
+
[
|
|
2004
|
+
TriccOperation(TriccOperator.ISTRUE, [TriccReference("pre_final." + code)]),
|
|
2005
|
+
TriccOperation(TriccOperator.SELECTED, [TriccReference("tricc.manual.diag"), TriccStatic(code)]),
|
|
2006
|
+
]
|
|
2007
|
+
),
|
|
1774
2008
|
)
|
|
1775
2009
|
return node
|
|
1776
2010
|
|
|
2011
|
+
|
|
1777
2012
|
def get_select_accept_reject_options(node, group):
|
|
1778
2013
|
yes = TriccNodeSelectOption(
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
2014
|
+
id=generate_id(f"accept{node.id}"),
|
|
2015
|
+
name=f"{TRICC_TRUE_VALUE}",
|
|
2016
|
+
label="Accept",
|
|
2017
|
+
select=node,
|
|
2018
|
+
group=group,
|
|
2019
|
+
list_name=node.list_name,
|
|
2020
|
+
)
|
|
1786
2021
|
no = TriccNodeSelectOption(
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
return {0:yes, 1:no
|
|
2022
|
+
id=generate_id(f"reject{node.id}"),
|
|
2023
|
+
name=f"{TRICC_FALSE_VALUE}",
|
|
2024
|
+
label="Reject",
|
|
2025
|
+
select=node,
|
|
2026
|
+
group=group,
|
|
2027
|
+
list_name=node.list_name,
|
|
2028
|
+
)
|
|
2029
|
+
return {0: yes, 1: no}
|
|
2030
|
+
|
|
1795
2031
|
|
|
1796
2032
|
def create_determine_diagnosis_activity(diags):
|
|
1797
2033
|
start = TriccNodeMainStart(
|
|
1798
|
-
id=generate_id(
|
|
1799
|
-
name="start.determine-diagnosis",
|
|
1800
|
-
process='determine-diagnosis'
|
|
2034
|
+
id=generate_id("start.determine-diagnosis"), name="start.determine-diagnosis", process="determine-diagnosis"
|
|
1801
2035
|
)
|
|
1802
2036
|
|
|
1803
|
-
|
|
1804
2037
|
activity = TriccNodeActivity(
|
|
1805
|
-
id=generate_id(
|
|
1806
|
-
name=
|
|
1807
|
-
label=
|
|
2038
|
+
id=generate_id("activity-determine-diagnosis"),
|
|
2039
|
+
name="determine-diagnosis",
|
|
2040
|
+
label="Classifications",
|
|
1808
2041
|
root=start,
|
|
1809
2042
|
)
|
|
1810
2043
|
|
|
1811
|
-
|
|
1812
2044
|
start.activity = activity
|
|
1813
2045
|
start.group = activity
|
|
1814
2046
|
diags_conf = []
|
|
@@ -1818,17 +2050,16 @@ def create_determine_diagnosis_activity(diags):
|
|
|
1818
2050
|
activity=activity,
|
|
1819
2051
|
group=activity,
|
|
1820
2052
|
)
|
|
1821
|
-
activity.nodes[end.id]=end
|
|
1822
|
-
|
|
2053
|
+
activity.nodes[end.id] = end
|
|
2054
|
+
|
|
1823
2055
|
f = TriccNodeSelectMultiple(
|
|
1824
2056
|
name="tricc.manual.diag",
|
|
1825
|
-
label="Add
|
|
1826
|
-
list_name=
|
|
2057
|
+
label="Add classifications",
|
|
2058
|
+
list_name="manual_diag",
|
|
1827
2059
|
id=generate_id("tricc.manual.diag"),
|
|
1828
2060
|
activity=activity,
|
|
1829
2061
|
group=activity,
|
|
1830
2062
|
required=TriccStatic(False),
|
|
1831
|
-
|
|
1832
2063
|
)
|
|
1833
2064
|
for proposed in diags:
|
|
1834
2065
|
d = get_accept_diagnostic_node(proposed.name, proposed.label, proposed.severity, proposed.priority, activity)
|
|
@@ -1837,14 +2068,12 @@ def create_determine_diagnosis_activity(diags):
|
|
|
1837
2068
|
r = TriccNodeRhombus(
|
|
1838
2069
|
path=start,
|
|
1839
2070
|
id=generate_id(f"proposed-rhombus{proposed.id}"),
|
|
1840
|
-
expression_reference=TriccOperation(
|
|
1841
|
-
TriccOperator.ISTRUE,
|
|
1842
|
-
[TriccReference(proposed.name)]
|
|
1843
|
-
),
|
|
2071
|
+
expression_reference=TriccOperation(TriccOperator.ISTRUE, [TriccReference(proposed.name)]),
|
|
1844
2072
|
reference=[TriccReference(proposed.name)],
|
|
1845
2073
|
activity=activity,
|
|
1846
2074
|
priority=proposed.priority,
|
|
1847
|
-
group=activity
|
|
2075
|
+
group=activity,
|
|
2076
|
+
)
|
|
1848
2077
|
activity.calculates.append(r)
|
|
1849
2078
|
activity.calculates.append(c)
|
|
1850
2079
|
set_prev_next_node(r, d, edge_only=False)
|
|
@@ -1852,11 +2081,11 @@ def create_determine_diagnosis_activity(diags):
|
|
|
1852
2081
|
wait2 = get_activity_wait([activity.root], diags_conf, [f], edge_only=False)
|
|
1853
2082
|
activity.nodes[d.options[0].id] = d.options[0]
|
|
1854
2083
|
activity.nodes[d.options[1].id] = d.options[1]
|
|
1855
|
-
activity.nodes[d.id]=d
|
|
1856
|
-
activity.nodes[r.id]=r
|
|
1857
|
-
activity.nodes[c.id]=c
|
|
1858
|
-
activity.nodes[f.id]=f
|
|
1859
|
-
activity.nodes[wait2.id]=wait2
|
|
2084
|
+
activity.nodes[d.id] = d
|
|
2085
|
+
activity.nodes[r.id] = r
|
|
2086
|
+
activity.nodes[c.id] = c
|
|
2087
|
+
activity.nodes[f.id] = f
|
|
2088
|
+
activity.nodes[wait2.id] = wait2
|
|
1860
2089
|
# fallback
|
|
1861
2090
|
|
|
1862
2091
|
options = [
|
|
@@ -1866,220 +2095,182 @@ def create_determine_diagnosis_activity(diags):
|
|
|
1866
2095
|
label=d.label,
|
|
1867
2096
|
list_name=f.list_name,
|
|
1868
2097
|
relevance=d.activity.applicability,
|
|
1869
|
-
select=f
|
|
1870
|
-
)
|
|
2098
|
+
select=f,
|
|
2099
|
+
)
|
|
2100
|
+
for d in diags
|
|
1871
2101
|
]
|
|
1872
|
-
f.options=dict(zip(range(0, len(options)), options))
|
|
1873
|
-
activity.nodes[f.id]=f
|
|
2102
|
+
f.options = dict(zip(range(0, len(options)), options))
|
|
2103
|
+
activity.nodes[f.id] = f
|
|
1874
2104
|
set_prev_next_node(f, end, edge_only=False)
|
|
1875
|
-
|
|
2105
|
+
|
|
1876
2106
|
return activity
|
|
1877
|
-
|
|
1878
|
-
|
|
2107
|
+
|
|
2108
|
+
|
|
2109
|
+
def get_prev_node_expression(node, processed_nodes, get_overall_exp=False, excluded_name=None, process=None):
|
|
1879
2110
|
expression = None
|
|
1880
2111
|
if node is None:
|
|
1881
2112
|
pass
|
|
1882
2113
|
# when getting the prev node, we calculate the
|
|
1883
|
-
if hasattr(node,
|
|
2114
|
+
if hasattr(node, "expression_inputs") and len(node.expression_inputs) > 0:
|
|
1884
2115
|
expression_inputs = node.expression_inputs
|
|
1885
2116
|
expression_inputs = clean_or_list(expression_inputs)
|
|
1886
2117
|
else:
|
|
1887
|
-
expression_inputs = []
|
|
2118
|
+
expression_inputs = []
|
|
1888
2119
|
prev_activities = {}
|
|
1889
2120
|
for prev_node in node.prev_nodes:
|
|
1890
2121
|
if prev_node.activity.id not in prev_activities:
|
|
1891
|
-
prev_activities[prev_node.activity.id]=[]
|
|
2122
|
+
prev_activities[prev_node.activity.id] = []
|
|
1892
2123
|
prev_activities[prev_node.activity.id].append(prev_node)
|
|
1893
|
-
|
|
2124
|
+
|
|
1894
2125
|
for act_id in prev_activities:
|
|
1895
2126
|
act_expression_inputs = []
|
|
1896
2127
|
for prev_node in prev_activities[act_id]:
|
|
1897
|
-
if
|
|
1898
|
-
|
|
2128
|
+
if (
|
|
2129
|
+
excluded_name is None
|
|
2130
|
+
or prev_node != excluded_name
|
|
2131
|
+
or (
|
|
2132
|
+
# or isinstance(prev_node, TriccNodeActivityEnd):
|
|
2133
|
+
isinstance(excluded_name, str)
|
|
2134
|
+
and hasattr(prev_node, "name")
|
|
2135
|
+
and prev_node.name != excluded_name
|
|
2136
|
+
)
|
|
2137
|
+
):
|
|
1899
2138
|
# the rhombus should calculate only reference
|
|
1900
2139
|
sub = get_node_expression(
|
|
1901
2140
|
prev_node,
|
|
1902
2141
|
processed_nodes=processed_nodes,
|
|
1903
2142
|
get_overall_exp=get_overall_exp,
|
|
1904
2143
|
is_prev=True,
|
|
1905
|
-
process=process
|
|
1906
|
-
|
|
1907
|
-
|
|
2144
|
+
process=process,
|
|
2145
|
+
)
|
|
2146
|
+
if isinstance(node, TriccNodeActivity) or get_overall_exp:
|
|
2147
|
+
add_sub_expression(act_expression_inputs, sub)
|
|
1908
2148
|
else:
|
|
1909
|
-
add_sub_expression(expression_inputs, sub
|
|
1910
|
-
|
|
2149
|
+
add_sub_expression(expression_inputs, sub)
|
|
2150
|
+
|
|
1911
2151
|
if act_expression_inputs:
|
|
1912
2152
|
act_sub = or_join(act_expression_inputs)
|
|
1913
|
-
if act_sub == TriccStatic(True):
|
|
1914
|
-
|
|
2153
|
+
if act_sub == TriccStatic(True):
|
|
2154
|
+
act_sub = get_node_expression(
|
|
1915
2155
|
prev_node.activity,
|
|
1916
2156
|
processed_nodes=processed_nodes,
|
|
1917
2157
|
get_overall_exp=True,
|
|
1918
2158
|
is_prev=True,
|
|
1919
2159
|
negate=False,
|
|
1920
|
-
process=process
|
|
2160
|
+
process=process,
|
|
1921
2161
|
)
|
|
1922
|
-
add_sub_expression(expression_inputs, act_sub
|
|
2162
|
+
add_sub_expression(expression_inputs, act_sub)
|
|
1923
2163
|
# avoid void is there is not conditions to avoid looping too much itme
|
|
1924
2164
|
# expression_inputs = clean_or_list(
|
|
1925
2165
|
# [
|
|
1926
|
-
# get_tricc_operation_operand(e)
|
|
1927
|
-
# if isinstance(expression, TriccOperation)
|
|
1928
|
-
# else e
|
|
2166
|
+
# get_tricc_operation_operand(e)
|
|
2167
|
+
# if isinstance(expression, TriccOperation)
|
|
2168
|
+
# else e
|
|
1929
2169
|
# for e in expression_inputs])
|
|
1930
|
-
|
|
2170
|
+
|
|
1931
2171
|
if expression_inputs:
|
|
1932
|
-
expression =
|
|
1933
|
-
expression_inputs
|
|
1934
|
-
)
|
|
2172
|
+
expression = or_join(expression_inputs)
|
|
1935
2173
|
# if isinstance(node, TriccNodeExclusive):
|
|
1936
2174
|
# expression = TRICC_NEGATE.format(expression)
|
|
1937
|
-
# only used for activityStart
|
|
2175
|
+
# only used for activityStart
|
|
1938
2176
|
else:
|
|
1939
2177
|
expression = TriccStatic(True)
|
|
1940
2178
|
return expression
|
|
1941
2179
|
|
|
1942
|
-
|
|
2180
|
+
|
|
2181
|
+
def get_activity_end_terms(node, processed_nodes, process=None):
|
|
1943
2182
|
end_nodes = node.get_end_nodes()
|
|
1944
2183
|
expression_inputs = []
|
|
1945
2184
|
for end_node in end_nodes:
|
|
1946
2185
|
add_sub_expression(
|
|
1947
2186
|
expression_inputs,
|
|
1948
2187
|
get_node_expression(
|
|
1949
|
-
end_node,
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
2188
|
+
end_node, processed_nodes=processed_nodes, get_overall_exp=False, is_prev=True, process=process
|
|
2189
|
+
),
|
|
2190
|
+
)
|
|
2191
|
+
|
|
2192
|
+
return or_join(expression_inputs)
|
|
1954
2193
|
|
|
1955
|
-
return or_join(expression_inputs)
|
|
1956
2194
|
|
|
1957
|
-
def get_count_terms(
|
|
2195
|
+
def get_count_terms(node, processed_nodes, get_overall_exp, negate=False, process=None):
|
|
1958
2196
|
terms = []
|
|
1959
|
-
|
|
2197
|
+
|
|
1960
2198
|
for prev_node in node.prev_nodes:
|
|
1961
|
-
term = get_count_terms_details(
|
|
2199
|
+
term = get_count_terms_details(prev_node, processed_nodes, get_overall_exp, negate, process)
|
|
1962
2200
|
if term:
|
|
1963
2201
|
terms.append(term)
|
|
1964
2202
|
if len(terms) == 1:
|
|
1965
|
-
return TriccOperation(
|
|
1966
|
-
TriccOperator.CAST_NUMBER,
|
|
1967
|
-
[terms[0]]
|
|
1968
|
-
)
|
|
2203
|
+
return TriccOperation(TriccOperator.CAST_NUMBER, [terms[0]])
|
|
1969
2204
|
elif len(terms) > 0:
|
|
1970
|
-
return TriccOperation(
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
TriccOperator.SELECTED,
|
|
1983
|
-
[
|
|
1984
|
-
prev_node,
|
|
1985
|
-
TriccStatic('opt_none')
|
|
1986
|
-
]
|
|
1987
|
-
)
|
|
1988
|
-
if isinstance(prev_node, TriccNodeSelectYesNo):
|
|
2205
|
+
return TriccOperation(TriccOperator.PLUS, [TriccOperation(TriccOperator.CAST_NUMBER, [term]) for term in terms])
|
|
2206
|
+
|
|
2207
|
+
|
|
2208
|
+
def get_count_terms_details(prev_node, processed_nodes, get_overall_exp, negate=False, process=None):
|
|
2209
|
+
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic("opt_none")])
|
|
2210
|
+
if isinstance(prev_node, TriccNodeSelectYesNo):
|
|
2211
|
+
return TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic(prev_node.options[0].name)])
|
|
2212
|
+
elif issubclass(prev_node.__class__, TriccNodeSelect):
|
|
2213
|
+
if negate:
|
|
2214
|
+
return
|
|
2215
|
+
# terms.append(TRICC_SELECT_MULTIPLE_CALC_NONE_EXPRESSION.format(get_export_name(prev_node)))
|
|
2216
|
+
else:
|
|
1989
2217
|
return TriccOperation(
|
|
1990
|
-
TriccOperator.
|
|
2218
|
+
TriccOperator.MINUS,
|
|
1991
2219
|
[
|
|
1992
|
-
prev_node,
|
|
1993
|
-
|
|
1994
|
-
]
|
|
2220
|
+
TriccOperation(TriccOperator.COUNT, [prev_node]),
|
|
2221
|
+
TriccOperation(TriccOperator.CAST_NUMBER, [operation_none]),
|
|
2222
|
+
],
|
|
1995
2223
|
)
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
TriccOperation(
|
|
2005
|
-
TriccOperator.NATIVE,
|
|
2006
|
-
[
|
|
2007
|
-
'count-selected',
|
|
2008
|
-
prev_node
|
|
2009
|
-
]
|
|
2010
|
-
),TriccOperation(
|
|
2011
|
-
TriccOperator.CAST_NUMBER,
|
|
2012
|
-
[
|
|
2013
|
-
operation_none
|
|
2014
|
-
]
|
|
2015
|
-
)
|
|
2016
|
-
])
|
|
2017
|
-
#terms.append(TRICC_SELECT_MULTIPLE_CALC_EXPRESSION.format(get_export_name(prev_node)))
|
|
2018
|
-
elif isinstance(prev_node, (TriccNodeSelectNotAvailable)):
|
|
2224
|
+
# terms.append(TRICC_SELECT_MULTIPLE_CALC_EXPRESSION.format(get_export_name(prev_node)))
|
|
2225
|
+
elif isinstance(prev_node, (TriccNodeSelectNotAvailable)):
|
|
2226
|
+
return TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic("1")])
|
|
2227
|
+
# terms.append(TRICC_SELECTED_EXPRESSION.format(get_export_name(prev_node), '1'))
|
|
2228
|
+
elif isinstance(prev_node, TriccNodeSelectOption):
|
|
2229
|
+
return get_selected_option_expression(prev_node, negate)
|
|
2230
|
+
else:
|
|
2231
|
+
if negate:
|
|
2019
2232
|
return TriccOperation(
|
|
2020
|
-
TriccOperator.
|
|
2233
|
+
TriccOperator.CAST_NUMBER,
|
|
2021
2234
|
[
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
]
|
|
2025
|
-
)
|
|
2026
|
-
#terms.append(TRICC_SELECTED_EXPRESSION.format(get_export_name(prev_node), '1'))
|
|
2027
|
-
elif isinstance(prev_node, TriccNodeSelectOption):
|
|
2028
|
-
return get_selected_option_expression(prev_node, negate)
|
|
2029
|
-
else:
|
|
2030
|
-
if negate:
|
|
2031
|
-
return TriccOperation(
|
|
2032
|
-
TriccOperator.CAST_NUMBER,
|
|
2235
|
+
TriccOperation(
|
|
2236
|
+
TriccOperator.NATIVE,
|
|
2033
2237
|
[
|
|
2034
2238
|
TriccOperation(
|
|
2035
|
-
TriccOperator.
|
|
2239
|
+
TriccOperator.CAST_NUMBER,
|
|
2036
2240
|
[
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
]
|
|
2049
|
-
)
|
|
2050
|
-
]
|
|
2241
|
+
get_node_expression(
|
|
2242
|
+
prev_node,
|
|
2243
|
+
processed_nodes=processed_nodes,
|
|
2244
|
+
get_overall_exp=True,
|
|
2245
|
+
is_prev=True,
|
|
2246
|
+
process=process,
|
|
2247
|
+
)
|
|
2248
|
+
],
|
|
2249
|
+
),
|
|
2250
|
+
TriccStatic("0"),
|
|
2251
|
+
],
|
|
2051
2252
|
)
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
is_prev=True,
|
|
2062
|
-
process=process)
|
|
2063
|
-
]
|
|
2253
|
+
],
|
|
2254
|
+
)
|
|
2255
|
+
|
|
2256
|
+
else:
|
|
2257
|
+
return TriccOperation(
|
|
2258
|
+
TriccOperator.CAST_NUMBER,
|
|
2259
|
+
[
|
|
2260
|
+
get_node_expression(
|
|
2261
|
+
prev_node, processed_nodes=processed_nodes, get_overall_exp=True, is_prev=True, process=process
|
|
2064
2262
|
)
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2263
|
+
],
|
|
2264
|
+
)
|
|
2265
|
+
|
|
2266
|
+
|
|
2267
|
+
def get_add_terms(node, processed_nodes, get_overall_exp=False, negate=False, process=None):
|
|
2069
2268
|
if negate:
|
|
2070
2269
|
logger.warning("negate not supported for Add node {}".format(node.get_name()))
|
|
2071
2270
|
terms = []
|
|
2072
2271
|
for prev_node in node.prev_nodes:
|
|
2073
2272
|
if issubclass(prev_node, TriccNodeNumber) or isinstance(node, TriccNodeCount):
|
|
2074
|
-
terms.append(
|
|
2075
|
-
TriccOperation(
|
|
2076
|
-
TriccOperator.COALESCE,
|
|
2077
|
-
[
|
|
2078
|
-
prev_node,
|
|
2079
|
-
TriccStatic(0)
|
|
2080
|
-
]
|
|
2081
|
-
)
|
|
2082
|
-
)
|
|
2273
|
+
terms.append(TriccOperation(TriccOperator.COALESCE, [prev_node, TriccStatic(0)]))
|
|
2083
2274
|
else:
|
|
2084
2275
|
terms.append(
|
|
2085
2276
|
TriccOperation(
|
|
@@ -2089,33 +2280,28 @@ def get_add_terms( node, processed_nodes, get_overall_exp=False, negate=False, p
|
|
|
2089
2280
|
prev_node,
|
|
2090
2281
|
processed_nodes=processed_nodes,
|
|
2091
2282
|
get_overall_exp=True,
|
|
2092
|
-
is_prev=True,
|
|
2093
|
-
process=process
|
|
2094
|
-
|
|
2283
|
+
is_prev=True,
|
|
2284
|
+
process=process,
|
|
2285
|
+
)
|
|
2286
|
+
],
|
|
2095
2287
|
)
|
|
2096
2288
|
)
|
|
2097
2289
|
if len(terms) > 0:
|
|
2098
2290
|
operation = terms[0]
|
|
2099
2291
|
if len(terms) > 1:
|
|
2100
2292
|
for term in terms[1:]:
|
|
2101
|
-
operation = TriccOperation(
|
|
2102
|
-
TriccOperator.ADD,
|
|
2103
|
-
[
|
|
2104
|
-
operation,
|
|
2105
|
-
term
|
|
2106
|
-
]
|
|
2107
|
-
)
|
|
2293
|
+
operation = TriccOperation(TriccOperator.ADD, [operation, term])
|
|
2108
2294
|
return operation
|
|
2109
|
-
|
|
2110
|
-
|
|
2295
|
+
|
|
2296
|
+
|
|
2297
|
+
def get_rhombus_terms(node, processed_nodes, get_overall_exp=False, negate=False, process=None):
|
|
2111
2298
|
expression = None
|
|
2112
2299
|
left_term = None
|
|
2113
|
-
operator = None
|
|
2114
2300
|
if node.reference is not None:
|
|
2115
2301
|
if isinstance(node.reference, set):
|
|
2116
2302
|
node.reference = list(node.reference)
|
|
2117
2303
|
# calcualte the expression only for select muzltiple and fake calculate
|
|
2118
|
-
if
|
|
2304
|
+
if issubclass(node.reference.__class__, (list, OrderedSet)):
|
|
2119
2305
|
if node.expression_reference is None and len(node.reference) == 1:
|
|
2120
2306
|
ref = node.reference[0]
|
|
2121
2307
|
if issubclass(ref.__class__, TriccNodeBaseModel):
|
|
@@ -2123,81 +2309,79 @@ def get_rhombus_terms( node, processed_nodes, get_overall_exp=False, negate=Fals
|
|
|
2123
2309
|
expression = get_activity_end_terms(ref, processed_nodes, process=process)
|
|
2124
2310
|
elif issubclass(ref.__class__, TriccNodeFakeCalculateBase):
|
|
2125
2311
|
expression = get_node_expression(
|
|
2126
|
-
ref,
|
|
2127
|
-
processed_nodes=processed_nodes,
|
|
2128
|
-
get_overall_exp=True,
|
|
2129
|
-
is_prev=True,
|
|
2130
|
-
process=process
|
|
2312
|
+
ref, processed_nodes=processed_nodes, get_overall_exp=True, is_prev=True, process=process
|
|
2131
2313
|
)
|
|
2132
2314
|
else:
|
|
2133
2315
|
expression = ref
|
|
2134
2316
|
elif issubclass(ref.__class__, TriccReference):
|
|
2135
2317
|
expression = ref
|
|
2136
2318
|
else:
|
|
2137
|
-
logger.critical(
|
|
2138
|
-
|
|
2319
|
+
logger.critical(
|
|
2320
|
+
"reference {0} was not found in the previous nodes of node {1}".format(
|
|
2321
|
+
node.reference, node.get_name()
|
|
2322
|
+
)
|
|
2323
|
+
)
|
|
2139
2324
|
exit(1)
|
|
2140
|
-
elif node.expression_reference is not None and node.expression_reference !=
|
|
2325
|
+
elif node.expression_reference is not None and node.expression_reference != "":
|
|
2141
2326
|
if isinstance(node.expression_reference, (TriccOperation, TriccReference, TriccStatic)):
|
|
2142
2327
|
return node.expression_reference
|
|
2143
2328
|
elif isinstance(node.expression_reference, str):
|
|
2144
2329
|
expression = node.expression_reference.format(*get_list_names(node.reference))
|
|
2145
2330
|
else:
|
|
2146
|
-
logger.critical(
|
|
2331
|
+
logger.critical(
|
|
2332
|
+
"expression_reference {0} unsuported type {1}".format(
|
|
2333
|
+
node.expression_reference, node.expression_reference.__class__.__name__
|
|
2334
|
+
)
|
|
2335
|
+
)
|
|
2147
2336
|
exit(1)
|
|
2148
2337
|
|
|
2149
2338
|
else:
|
|
2150
2339
|
logger.warning("missing expression for node {}".format(node.get_name()))
|
|
2151
2340
|
else:
|
|
2152
|
-
logger.critical(
|
|
2341
|
+
logger.critical("reference {0} is not a list {1}".format(node.reference, node.get_name()))
|
|
2153
2342
|
exit(1)
|
|
2154
2343
|
else:
|
|
2155
|
-
logger.critical(
|
|
2344
|
+
logger.critical("reference empty for Rhombis {}".format(node.get_name()))
|
|
2156
2345
|
exit(1)
|
|
2157
2346
|
|
|
2158
2347
|
if expression is not None:
|
|
2159
2348
|
if isinstance(expression, (TriccOperation, TriccStatic)):
|
|
2160
2349
|
return expression
|
|
2161
|
-
elif issubclass(expression.__class__
|
|
2350
|
+
elif issubclass(expression.__class__, TriccNodeCalculateBase):
|
|
2162
2351
|
return TriccOperation(
|
|
2163
2352
|
TriccOperator.CAST_NUMBER,
|
|
2164
2353
|
[
|
|
2165
2354
|
get_node_expression(
|
|
2166
|
-
expression,
|
|
2167
|
-
processed_nodes=processed_nodes,
|
|
2168
|
-
get_overall_exp=True,
|
|
2169
|
-
is_prev=True,
|
|
2170
|
-
process=process
|
|
2355
|
+
expression, processed_nodes=processed_nodes, get_overall_exp=True, is_prev=True, process=process
|
|
2171
2356
|
)
|
|
2172
|
-
]
|
|
2173
|
-
elif issubclass(expression.__class__ , (TriccOperation) ):
|
|
2174
|
-
return expression
|
|
2175
|
-
elif issubclass(expression.__class__ , (TriccNodeDisplayModel, TriccReference)):
|
|
2176
|
-
return TriccOperation(
|
|
2177
|
-
TriccOperator.ISTRUE,
|
|
2178
|
-
[
|
|
2179
|
-
expression
|
|
2180
|
-
]
|
|
2357
|
+
],
|
|
2181
2358
|
)
|
|
2359
|
+
elif issubclass(expression.__class__, (TriccOperation)):
|
|
2360
|
+
return expression
|
|
2361
|
+
elif issubclass(expression.__class__, (TriccNodeDisplayModel, TriccReference)):
|
|
2362
|
+
return TriccOperation(TriccOperator.ISTRUE, [expression])
|
|
2182
2363
|
else:
|
|
2183
2364
|
if left_term is not None and re.search(" (+)|(-)|(or)|(and) ", expression):
|
|
2184
2365
|
expression = "({0}){1}".format(expression, left_term)
|
|
2185
2366
|
else:
|
|
2186
2367
|
expression = "{0}{1}".format(expression, left_term)
|
|
2187
2368
|
else:
|
|
2188
|
-
logger.critical(
|
|
2189
|
-
node.get_name(),
|
|
2190
|
-
|
|
2191
|
-
))
|
|
2369
|
+
logger.critical(
|
|
2370
|
+
"Rhombus reference was not found for node {}, reference {}".format(node.get_name(), node.reference)
|
|
2371
|
+
)
|
|
2192
2372
|
exit(1)
|
|
2193
2373
|
|
|
2194
2374
|
return expression
|
|
2375
|
+
|
|
2376
|
+
|
|
2195
2377
|
# function that generate the calculation terms return by calculate node
|
|
2196
2378
|
# @param node calculate node to assess
|
|
2197
2379
|
# @param processed_nodes list of node already processed, importnat because only processed node could be use
|
|
2198
2380
|
# @param get_overall_exp used when this funciton is called in the evaluation of another calculate
|
|
2199
2381
|
# @param negate use to retriece the negation of a calculation
|
|
2200
|
-
|
|
2382
|
+
|
|
2383
|
+
|
|
2384
|
+
def get_calculation_terms(node, processed_nodes, get_overall_exp=False, negate=False, process=None):
|
|
2201
2385
|
# returns something directly only if the negate is managed
|
|
2202
2386
|
expression = None
|
|
2203
2387
|
if isinstance(node, TriccNodeAdd):
|
|
@@ -2206,22 +2390,25 @@ def get_calculation_terms( node, processed_nodes, get_overall_exp=False, negate=
|
|
|
2206
2390
|
return get_count_terms(node, False, negate, process=process)
|
|
2207
2391
|
elif isinstance(node, TriccNodeRhombus):
|
|
2208
2392
|
return get_rhombus_terms(
|
|
2209
|
-
node,
|
|
2210
|
-
processed_nodes=processed_nodes,
|
|
2211
|
-
get_overall_exp=False,
|
|
2212
|
-
negate=negate,
|
|
2213
|
-
process=process
|
|
2393
|
+
node, processed_nodes=processed_nodes, get_overall_exp=False, negate=negate, process=process
|
|
2214
2394
|
)
|
|
2215
|
-
elif isinstance(node, (
|
|
2395
|
+
elif isinstance(node, (TriccNodeWait)):
|
|
2216
2396
|
# just use to force order of question
|
|
2217
2397
|
expression = None
|
|
2218
|
-
# in case of calulate expression evaluation, we need to get the relevance of the activity
|
|
2398
|
+
# in case of calulate expression evaluation, we need to get the relevance of the activity
|
|
2219
2399
|
# because calculate are not the the activity group
|
|
2220
2400
|
elif isinstance(node, (TriccNodeActivityStart)) and get_overall_exp:
|
|
2221
|
-
expression =
|
|
2401
|
+
expression = get_prev_node_expression(
|
|
2402
|
+
node.activity,
|
|
2403
|
+
processed_nodes=processed_nodes,
|
|
2404
|
+
get_overall_exp=get_overall_exp,
|
|
2405
|
+
negate=negate,
|
|
2406
|
+
process=process,
|
|
2407
|
+
)
|
|
2222
2408
|
elif isinstance(node, (TriccNodeActivityStart, TriccNodeActivityEnd)):
|
|
2223
2409
|
# the group have the relevance for the activity, not needed to replicate it
|
|
2224
|
-
|
|
2410
|
+
# return get_prev_node_expression(node.activity, processed_nodes, get_overall_exp=False, excluded_name=None)
|
|
2411
|
+
expression = None
|
|
2225
2412
|
elif isinstance(node, TriccNodeExclusive):
|
|
2226
2413
|
if len(node.prev_nodes) == 1:
|
|
2227
2414
|
iterator = iter(node.prev_nodes)
|
|
@@ -2236,8 +2423,8 @@ def get_calculation_terms( node, processed_nodes, get_overall_exp=False, negate=
|
|
|
2236
2423
|
get_overall_exp=True,
|
|
2237
2424
|
is_prev=True,
|
|
2238
2425
|
negate=True,
|
|
2239
|
-
process=process
|
|
2240
|
-
|
|
2426
|
+
process=process,
|
|
2427
|
+
)
|
|
2241
2428
|
elif isinstance(node_to_negate, TriccNodeActivity):
|
|
2242
2429
|
return get_node_expression(
|
|
2243
2430
|
node_to_negate,
|
|
@@ -2245,36 +2432,45 @@ def get_calculation_terms( node, processed_nodes, get_overall_exp=False, negate=
|
|
|
2245
2432
|
get_overall_exp=True,
|
|
2246
2433
|
is_prev=True,
|
|
2247
2434
|
negate=True,
|
|
2248
|
-
process=process
|
|
2435
|
+
process=process,
|
|
2249
2436
|
)
|
|
2250
2437
|
else:
|
|
2251
|
-
logger.critical(
|
|
2438
|
+
logger.critical(
|
|
2439
|
+
f"exclusive node {node.get_name()}\
|
|
2252
2440
|
does not depend of a calculate but on\
|
|
2253
|
-
{node_to_negate.__class__}::{node_to_negate.get_name()}"
|
|
2441
|
+
{node_to_negate.__class__}::{node_to_negate.get_name()}"
|
|
2442
|
+
)
|
|
2254
2443
|
|
|
2255
2444
|
else:
|
|
2256
2445
|
logger.critical("exclusive node {} has no ou too much parent".format(node.get_name()))
|
|
2257
|
-
|
|
2446
|
+
|
|
2258
2447
|
if isinstance(node.expression_reference, (TriccOperation, TriccStatic)):
|
|
2259
2448
|
expression = node.expression_reference
|
|
2260
|
-
elif node.reference is not None and node.expression_reference is not None
|
|
2261
|
-
expression = get_prev_node_expression(
|
|
2449
|
+
elif node.reference is not None and node.expression_reference is not None:
|
|
2450
|
+
expression = get_prev_node_expression(
|
|
2451
|
+
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, process=process
|
|
2452
|
+
)
|
|
2262
2453
|
ref_expression = node.expression_reference.format(*[get_export_name(ref) for ref in node.reference])
|
|
2263
|
-
if expression is not None and expression !=
|
|
2264
|
-
expression =
|
|
2454
|
+
if expression is not None and expression != "":
|
|
2455
|
+
expression = and_join([expression, ref_expression])
|
|
2265
2456
|
else:
|
|
2266
2457
|
expression = ref_expression
|
|
2267
2458
|
elif expression is None:
|
|
2268
|
-
expression =
|
|
2269
|
-
|
|
2459
|
+
expression = get_prev_node_expression(
|
|
2460
|
+
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, process=process
|
|
2461
|
+
)
|
|
2462
|
+
|
|
2270
2463
|
# manage the generic negation
|
|
2271
2464
|
if negate:
|
|
2272
|
-
|
|
2465
|
+
|
|
2273
2466
|
return negate_term(expression)
|
|
2274
2467
|
else:
|
|
2275
2468
|
return expression
|
|
2276
|
-
|
|
2469
|
+
|
|
2470
|
+
|
|
2277
2471
|
# Function that add element to array is not None or ''
|
|
2472
|
+
|
|
2473
|
+
|
|
2278
2474
|
def add_sub_expression(array, sub):
|
|
2279
2475
|
if isinstance(sub, (TriccOperation, TriccStatic)):
|
|
2280
2476
|
not_sub = negate_term(sub)
|
|
@@ -2288,62 +2484,36 @@ def add_sub_expression(array, sub):
|
|
|
2288
2484
|
pass
|
|
2289
2485
|
# elif sub is None:
|
|
2290
2486
|
# array.append(TriccStatic(True))
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
2487
|
|
|
2294
2488
|
# function that negate terms
|
|
2489
|
+
|
|
2490
|
+
|
|
2295
2491
|
# @param expression to negate
|
|
2296
|
-
def negate_term(expression):
|
|
2297
|
-
|
|
2298
|
-
return not_clean(expression)
|
|
2299
2492
|
|
|
2300
2493
|
|
|
2494
|
+
def negate_term(expression):
|
|
2495
|
+
|
|
2496
|
+
return not_clean(expression)
|
|
2301
2497
|
|
|
2302
2498
|
|
|
2303
2499
|
# if the node is "required" then we can take the fact that it has value for the next elements
|
|
2304
2500
|
def get_required_node_expression(node):
|
|
2305
|
-
return TriccOperation(
|
|
2306
|
-
operator=TriccOperator.EXISTS,
|
|
2307
|
-
reference=[
|
|
2308
|
-
node
|
|
2309
|
-
]
|
|
2310
|
-
)
|
|
2501
|
+
return TriccOperation(operator=TriccOperator.EXISTS, reference=[node])
|
|
2311
2502
|
|
|
2312
2503
|
|
|
2313
2504
|
# Get a selected option
|
|
2314
2505
|
def get_selected_option_expression(option_node, negate):
|
|
2315
|
-
|
|
2316
|
-
selected = TriccOperation(
|
|
2317
|
-
|
|
2318
|
-
[
|
|
2319
|
-
option_node.select,
|
|
2320
|
-
TriccStatic(option_node.name)
|
|
2321
|
-
]
|
|
2322
|
-
)
|
|
2323
|
-
|
|
2506
|
+
|
|
2507
|
+
selected = TriccOperation(TriccOperator.SELECTED, [option_node.select, TriccStatic(option_node.name)])
|
|
2508
|
+
|
|
2324
2509
|
if negate:
|
|
2325
2510
|
return TriccOperation(
|
|
2326
2511
|
operator=TriccOperator.AND,
|
|
2327
2512
|
resource=[
|
|
2328
|
-
TriccOperation(
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
),TriccOperation(
|
|
2334
|
-
operator=TriccOperator.NATIVE,
|
|
2335
|
-
resource=[
|
|
2336
|
-
'count-selected',
|
|
2337
|
-
option_node.select
|
|
2338
|
-
]
|
|
2339
|
-
)
|
|
2340
|
-
])
|
|
2341
|
-
|
|
2513
|
+
TriccOperation(operator=TriccOperator.NOT, resource=[selected]),
|
|
2514
|
+
TriccOperation(operator=TriccOperator.NATIVE, resource=["count-selected", option_node.select]),
|
|
2515
|
+
],
|
|
2516
|
+
)
|
|
2517
|
+
|
|
2342
2518
|
else:
|
|
2343
2519
|
return selected
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|