tricc-oo 1.6.25__py3-none-any.whl → 1.7.0.dev1__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/test_build.py +260 -0
- tests/test_cql.py +0 -9
- tricc_oo/converters/codesystem_to_ocl.py +4 -4
- tricc_oo/converters/cql_to_operation.py +0 -1
- tricc_oo/converters/datadictionnary.py +2 -2
- tricc_oo/converters/drawio_type_map.py +11 -11
- tricc_oo/converters/tricc_to_xls_form.py +4 -5
- tricc_oo/converters/xml_to_tricc.py +34 -55
- tricc_oo/models/base.py +1 -7
- tricc_oo/models/tricc.py +1 -5
- tricc_oo/serializers/xls_form.py +34 -90
- tricc_oo/strategies/output/base_output_strategy.py +0 -7
- tricc_oo/strategies/output/dhis2_form.py +8 -8
- tricc_oo/strategies/output/openmrs_form.py +2 -2
- tricc_oo/strategies/output/xls_form.py +49 -133
- tricc_oo/strategies/output/xlsform_cht.py +4 -129
- tricc_oo/visitors/tricc.py +106 -222
- {tricc_oo-1.6.25.dist-info → tricc_oo-1.7.0.dev1.dist-info}/METADATA +1 -1
- {tricc_oo-1.6.25.dist-info → tricc_oo-1.7.0.dev1.dist-info}/RECORD +22 -21
- {tricc_oo-1.6.25.dist-info → tricc_oo-1.7.0.dev1.dist-info}/WHEEL +1 -1
- {tricc_oo-1.6.25.dist-info → tricc_oo-1.7.0.dev1.dist-info}/licenses/LICENSE +0 -0
- {tricc_oo-1.6.25.dist-info → tricc_oo-1.7.0.dev1.dist-info}/top_level.txt +0 -0
tricc_oo/visitors/tricc.py
CHANGED
|
@@ -56,9 +56,6 @@ from tricc_oo.converters.tricc_to_xls_form import get_list_names, get_export_nam
|
|
|
56
56
|
logger = logging.getLogger("default")
|
|
57
57
|
ONE_QUESTION_AT_A_TIME = False
|
|
58
58
|
|
|
59
|
-
# Track the last group that was reordered to avoid unnecessary reordering
|
|
60
|
-
_last_reordered_group = None
|
|
61
|
-
|
|
62
59
|
|
|
63
60
|
def merge_node(from_node, to_node):
|
|
64
61
|
if from_node.activity != to_node.activity:
|
|
@@ -124,10 +121,7 @@ def get_last_version(name, processed_nodes, _list=None):
|
|
|
124
121
|
# node is the node to calculate
|
|
125
122
|
# processed_nodes are the list of processed nodes
|
|
126
123
|
def get_node_expressions(node, processed_nodes, process=None):
|
|
127
|
-
get_overall_exp = issubclass(
|
|
128
|
-
node.__class__,
|
|
129
|
-
(TriccNodeDisplayCalculateBase, TriccNodeProposedDiagnosis, TriccNodeDiagnosis)
|
|
130
|
-
) and not isinstance(node, (TriccNodeDisplayBridge))
|
|
124
|
+
get_overall_exp = issubclass(node.__class__, (TriccNodeDisplayCalculateBase, TriccNodeProposedDiagnosis, TriccNodeDiagnosis)) and not isinstance(node, (TriccNodeDisplayBridge))
|
|
131
125
|
expression = None
|
|
132
126
|
# in case of recursive call processed_nodes will be None
|
|
133
127
|
if processed_nodes is None or is_ready_to_process(node, processed_nodes=processed_nodes):
|
|
@@ -158,25 +152,19 @@ def set_last_version_false(node, processed_nodes):
|
|
|
158
152
|
return last_version
|
|
159
153
|
|
|
160
154
|
|
|
161
|
-
def get_version_inheritance(node,
|
|
162
|
-
|
|
163
|
-
#
|
|
164
|
-
# This ensures inheritance works even when intermediate activities weren't triggered
|
|
165
|
-
|
|
155
|
+
def get_version_inheritance(node, last_version, processed_nodes):
|
|
156
|
+
# FIXME this is for XLS form where only calculate are evaluated
|
|
157
|
+
# for a activity that is not triggered
|
|
166
158
|
if not issubclass(node.__class__, (TriccNodeInputModel)):
|
|
167
159
|
node.last = True
|
|
168
160
|
if issubclass(node.__class__, (TriccNodeDisplayCalculateBase, TriccNodeEnd)) and node.name is not None:
|
|
169
161
|
# logger.debug("set last to false for node {}
|
|
170
162
|
# and add its link it to next one".format(last_used_calc.get_name()))
|
|
171
163
|
if node.prev_nodes:
|
|
172
|
-
|
|
173
|
-
for pv in all_prev_versions:
|
|
174
|
-
set_prev_next_node(pv, node)
|
|
164
|
+
set_prev_next_node(last_version, node)
|
|
175
165
|
else:
|
|
176
166
|
expression = node.expression or node.expression_reference or getattr(node, "relevance", None)
|
|
177
|
-
|
|
178
|
-
if all_prev_versions:
|
|
179
|
-
expression = merge_all_expressions(expression, all_prev_versions)
|
|
167
|
+
expression = merge_expression(expression, last_version)
|
|
180
168
|
if node.expression:
|
|
181
169
|
node.expression = expression
|
|
182
170
|
elif node.expression_reference:
|
|
@@ -185,25 +173,21 @@ def get_version_inheritance(node, all_prev_versions, processed_nodes):
|
|
|
185
173
|
node.relevance = expression
|
|
186
174
|
else:
|
|
187
175
|
node.last = False
|
|
188
|
-
|
|
189
|
-
# Create a calculate node that coalesces all previous saved values with the current node value
|
|
190
|
-
calc_id = generate_id(f"save_{node.save}")
|
|
191
|
-
|
|
192
|
-
# Build reference list with current node and all previous versions
|
|
193
|
-
reference_list = [node] + (all_prev_versions if all_prev_versions else [])
|
|
194
176
|
|
|
177
|
+
# Create a calculate node that coalesces the previous saved value with the current node value
|
|
178
|
+
calc_id = generate_id(f"save_{node.save}")
|
|
195
179
|
calc = TriccNodeCalculate(
|
|
196
180
|
id=calc_id,
|
|
197
181
|
name=node.save,
|
|
198
182
|
path_len=node.path_len + 1,
|
|
199
183
|
expression_reference=TriccOperation(
|
|
200
184
|
TriccOperator.COALESCE,
|
|
201
|
-
|
|
185
|
+
[TriccReference(node.save), last_version],
|
|
202
186
|
),
|
|
203
|
-
reference=
|
|
187
|
+
reference=[TriccReference(n.name)],
|
|
204
188
|
activity=node.activity,
|
|
205
189
|
group=node.group,
|
|
206
|
-
label=f"Save calculation for {
|
|
190
|
+
label=f"Save calculation for {n.label}",
|
|
207
191
|
last=True,
|
|
208
192
|
)
|
|
209
193
|
node.activity.nodes[calc.id] = calc
|
|
@@ -211,9 +195,7 @@ def get_version_inheritance(node, all_prev_versions, processed_nodes):
|
|
|
211
195
|
# set_last_version_false(calc, processed_nodes)
|
|
212
196
|
processed_nodes.add(calc)
|
|
213
197
|
if issubclass(node.__class__, TriccNodeInputModel):
|
|
214
|
-
|
|
215
|
-
coalesce_operands = ["$this"] + (all_prev_versions if all_prev_versions else [])
|
|
216
|
-
node.expression = TriccOperation(TriccOperator.COALESCE, coalesce_operands)
|
|
198
|
+
node.expression = TriccOperation(TriccOperator.COALESCE, ["$this", last_version])
|
|
217
199
|
|
|
218
200
|
|
|
219
201
|
def merge_expression(expression, last_version):
|
|
@@ -228,30 +210,6 @@ def merge_expression(expression, last_version):
|
|
|
228
210
|
return expression
|
|
229
211
|
|
|
230
212
|
|
|
231
|
-
def merge_all_expressions(expression, all_versions):
|
|
232
|
-
"""
|
|
233
|
-
Merge an expression with ALL previous versions, not just the last one.
|
|
234
|
-
This ensures inheritance works even when intermediate versions weren't evaluated
|
|
235
|
-
due to activity relevance conditions.
|
|
236
|
-
"""
|
|
237
|
-
if not all_versions:
|
|
238
|
-
return expression
|
|
239
|
-
|
|
240
|
-
datatype = expression.get_datatype() if expression else "unknown"
|
|
241
|
-
|
|
242
|
-
if datatype == "boolean":
|
|
243
|
-
expression = or_join([expression, *all_versions])
|
|
244
|
-
|
|
245
|
-
else:
|
|
246
|
-
# COALESCE through all previous versions, then the current expression
|
|
247
|
-
coalesce_operands = list(all_versions)
|
|
248
|
-
if expression:
|
|
249
|
-
coalesce_operands.append(expression)
|
|
250
|
-
expression = TriccOperation(TriccOperator.COALESCE, coalesce_operands)
|
|
251
|
-
|
|
252
|
-
return expression
|
|
253
|
-
|
|
254
|
-
|
|
255
213
|
def load_calculate(
|
|
256
214
|
node, processed_nodes, stashed_nodes, calculates, used_calculates, warn=False, process=None, **kwargs
|
|
257
215
|
):
|
|
@@ -275,14 +233,8 @@ def load_calculate(
|
|
|
275
233
|
# tricc diagnostic have the same name as proposed diag but will be serialised with different names
|
|
276
234
|
|
|
277
235
|
last_version = set_last_version_false(node, processed_nodes)
|
|
278
|
-
# Get all previous versions from processed_nodes, not just the last one
|
|
279
|
-
node_name = node.name if not isinstance(node, TriccNodeEnd) else node.get_reference()
|
|
280
|
-
all_prev_versions = get_versions(node_name, processed_nodes)
|
|
281
|
-
# Exclude the current node itself
|
|
282
|
-
all_prev_versions = [v for v in all_prev_versions if v != node]
|
|
283
|
-
|
|
284
236
|
if last_version:
|
|
285
|
-
get_version_inheritance(node,
|
|
237
|
+
last_version = get_version_inheritance(node, last_version, processed_nodes)
|
|
286
238
|
|
|
287
239
|
generate_calculates(node, calculates, used_calculates, processed_nodes=processed_nodes, process=process)
|
|
288
240
|
|
|
@@ -450,11 +402,6 @@ def get_bridge_path(prev_nodes, node=None, edge_only=False):
|
|
|
450
402
|
calc = TriccNodeDisplayBridge(**data)
|
|
451
403
|
else:
|
|
452
404
|
calc = TriccNodeBridge(**data)
|
|
453
|
-
if node:
|
|
454
|
-
priority = getattr(node, 'priority', None)
|
|
455
|
-
if priority:
|
|
456
|
-
calc.priority = priority
|
|
457
|
-
|
|
458
405
|
return calc
|
|
459
406
|
|
|
460
407
|
|
|
@@ -855,7 +802,7 @@ def process_operation_reference(
|
|
|
855
802
|
operation,
|
|
856
803
|
node,
|
|
857
804
|
processed_nodes,
|
|
858
|
-
calculates
|
|
805
|
+
calculates,
|
|
859
806
|
used_calculates=None,
|
|
860
807
|
replace_reference=False,
|
|
861
808
|
warn=False,
|
|
@@ -1018,7 +965,6 @@ def walktrhough_tricc_node_processed_stached(
|
|
|
1018
965
|
warn=False,
|
|
1019
966
|
node_path=[],
|
|
1020
967
|
process=None,
|
|
1021
|
-
loop_count=0,
|
|
1022
968
|
**kwargs,
|
|
1023
969
|
):
|
|
1024
970
|
ended_activity = False
|
|
@@ -1184,10 +1130,7 @@ def walktrhough_tricc_node_processed_stached(
|
|
|
1184
1130
|
if nn not in stashed_nodes:
|
|
1185
1131
|
stashed_nodes.insert_at_top(nn)
|
|
1186
1132
|
if not recursive:
|
|
1187
|
-
|
|
1188
|
-
if _last_reordered_group != node.group:
|
|
1189
|
-
reorder_node_list(stashed_nodes, node.group, processed_nodes)
|
|
1190
|
-
_last_reordered_group = node.group
|
|
1133
|
+
reorder_node_list(stashed_nodes, node.group, processed_nodes)
|
|
1191
1134
|
|
|
1192
1135
|
else:
|
|
1193
1136
|
if prev_process and process and prev_process != process[0]:
|
|
@@ -1334,7 +1277,7 @@ def stashed_node_func(node, callback, recursive=False, **kwargs):
|
|
|
1334
1277
|
|
|
1335
1278
|
|
|
1336
1279
|
# check if the all the prev nodes are processed
|
|
1337
|
-
def is_ready_to_process(in_node, processed_nodes, strict=True, local=False
|
|
1280
|
+
def is_ready_to_process(in_node, processed_nodes, strict=True, local=False):
|
|
1338
1281
|
if isinstance(in_node, TriccNodeSelectOption):
|
|
1339
1282
|
node = in_node.select
|
|
1340
1283
|
elif isinstance(in_node, (TriccNodeActivityStart, TriccNodeMainStart)):
|
|
@@ -1345,38 +1288,36 @@ def is_ready_to_process(in_node, processed_nodes, strict=True, local=False, loop
|
|
|
1345
1288
|
if hasattr(node, "prev_nodes"):
|
|
1346
1289
|
# ensure the previous node of the select are processed, not the option prev nodes
|
|
1347
1290
|
for prev_node in node.prev_nodes:
|
|
1348
|
-
if is_prev_processed(prev_node, node, processed_nodes, local
|
|
1291
|
+
if is_prev_processed(prev_node, node, processed_nodes, local) is False:
|
|
1349
1292
|
return False
|
|
1350
1293
|
return True
|
|
1351
1294
|
|
|
1352
1295
|
|
|
1353
|
-
def is_prev_processed(prev_node, node, processed_nodes, local
|
|
1296
|
+
def is_prev_processed(prev_node, node, processed_nodes, local):
|
|
1354
1297
|
if hasattr(prev_node, "select"):
|
|
1355
|
-
return is_prev_processed(prev_node.select, node, processed_nodes, local
|
|
1298
|
+
return is_prev_processed(prev_node.select, node, processed_nodes, local)
|
|
1356
1299
|
if prev_node not in processed_nodes and (not local):
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
"is_ready_to_process:failed:via_excl: {} - {} > {} {}:{}".format(
|
|
1364
|
-
get_data_for_log(p_n_node), prev_node.get_name(), node.__class__, node.get_name(), node.instance
|
|
1365
|
-
)
|
|
1366
|
-
)
|
|
1367
|
-
|
|
1368
|
-
else:
|
|
1369
|
-
logger.debug(
|
|
1370
|
-
"is_ready_to_process:failed: {} -> {} {}:{}".format(
|
|
1371
|
-
get_data_for_log(prev_node), node.__class__, node.get_name(), node.instance
|
|
1372
|
-
)
|
|
1300
|
+
if isinstance(prev_node, TriccNodeExclusive):
|
|
1301
|
+
iterator = iter(prev_node.prev_nodes)
|
|
1302
|
+
p_n_node = next(iterator)
|
|
1303
|
+
logger.debug(
|
|
1304
|
+
"is_ready_to_process:failed:via_excl: {} - {} > {} {}:{}".format(
|
|
1305
|
+
get_data_for_log(p_n_node), prev_node.get_name(), node.__class__, node.get_name(), node.instance
|
|
1373
1306
|
)
|
|
1307
|
+
)
|
|
1374
1308
|
|
|
1309
|
+
else:
|
|
1375
1310
|
logger.debug(
|
|
1376
|
-
"
|
|
1377
|
-
prev_node.__class__,
|
|
1311
|
+
"is_ready_to_process:failed: {} -> {} {}:{}".format(
|
|
1312
|
+
get_data_for_log(prev_node), node.__class__, node.get_name(), node.instance
|
|
1378
1313
|
)
|
|
1379
1314
|
)
|
|
1315
|
+
|
|
1316
|
+
logger.debug(
|
|
1317
|
+
"prev node node {}:{} for node {} not in processed".format(
|
|
1318
|
+
prev_node.__class__, prev_node.get_name(), node.get_name()
|
|
1319
|
+
)
|
|
1320
|
+
)
|
|
1380
1321
|
return False
|
|
1381
1322
|
return True
|
|
1382
1323
|
|
|
@@ -1791,36 +1732,28 @@ def replace_next_node(prev_node, next_node, old_node):
|
|
|
1791
1732
|
|
|
1792
1733
|
|
|
1793
1734
|
# Priority constants
|
|
1794
|
-
SAME_GROUP_PRIORITY =
|
|
1795
|
-
PARENT_GROUP_PRIORITY =
|
|
1796
|
-
ACTIVE_ACTIVITY_PRIORITY =
|
|
1797
|
-
NON_START_ACTIVITY_PRIORITY =
|
|
1798
|
-
ACTIVE_ACTIVITY_LOWER_PRIORITY =
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1735
|
+
SAME_GROUP_PRIORITY = 7000
|
|
1736
|
+
PARENT_GROUP_PRIORITY = 6000
|
|
1737
|
+
ACTIVE_ACTIVITY_PRIORITY = 5000
|
|
1738
|
+
NON_START_ACTIVITY_PRIORITY = 4000
|
|
1739
|
+
ACTIVE_ACTIVITY_LOWER_PRIORITY = 3000
|
|
1740
|
+
RHOMBUS_PRIORITY = 1000
|
|
1741
|
+
DEFAULT_PRIORITY = 2000
|
|
1742
|
+
|
|
1743
|
+
|
|
1803
1744
|
def reorder_node_list(node_list, group, processed_nodes):
|
|
1804
1745
|
# Cache active activities for O(1) lookup
|
|
1805
1746
|
active_activities = {n.activity for n in processed_nodes}
|
|
1806
|
-
MAP_PRIORITIES = {}
|
|
1807
|
-
def get_priority(node):
|
|
1808
|
-
if node.id in MAP_PRIORITIES:
|
|
1809
|
-
return MAP_PRIORITIES[node.id]
|
|
1810
|
-
if isinstance(node, (TriccNodeActivityStart, TriccNodeMainStart)):
|
|
1811
|
-
return get_priority(node.activity)
|
|
1812
|
-
if isinstance(node, (TriccNodeSelectOption)):
|
|
1813
|
-
return get_priority(node.select)
|
|
1814
1747
|
|
|
1748
|
+
def get_priority(node):
|
|
1815
1749
|
# Cache attributes to avoid repeated getattr calls
|
|
1816
|
-
|
|
1817
|
-
priority = int(explicit_priority or 0)
|
|
1750
|
+
priority = int(getattr(node, "priority", 0) or 0)
|
|
1818
1751
|
node_group = getattr(node, "group", None)
|
|
1819
1752
|
activity = getattr(node, "activity", None)
|
|
1820
1753
|
|
|
1821
1754
|
# Check for same group
|
|
1822
1755
|
if group is not None and node_group and node_group.id == group.id:
|
|
1823
|
-
priority += SAME_GROUP_PRIORITY
|
|
1756
|
+
priority += SAME_GROUP_PRIORITY
|
|
1824
1757
|
# Check for parent group
|
|
1825
1758
|
elif hasattr(group, "group") and group.group and node_group and node_group.id == group.group.id:
|
|
1826
1759
|
priority += PARENT_GROUP_PRIORITY
|
|
@@ -1834,21 +1767,11 @@ def reorder_node_list(node_list, group, processed_nodes):
|
|
|
1834
1767
|
elif activity and activity in active_activities:
|
|
1835
1768
|
priority += ACTIVE_ACTIVITY_LOWER_PRIORITY
|
|
1836
1769
|
# Check for rhombus nodes
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
if (
|
|
1840
|
-
issubclass(node.__class__, TriccNodeDisplayCalculateBase) or
|
|
1841
|
-
isinstance(node, TriccNodeEnd)
|
|
1842
|
-
) and not isinstance(node, TriccNodeActivityEnd) and hasattr(node, 'prev_nodes') and len(node.prev_nodes) > 0:
|
|
1843
|
-
priority += FLOW_CALCULATE_NODE_PRIORITY_TOP_UP
|
|
1844
1770
|
elif issubclass(node.__class__, TriccRhombusMixIn):
|
|
1845
|
-
priority +=
|
|
1771
|
+
priority += RHOMBUS_PRIORITY
|
|
1772
|
+
else:
|
|
1773
|
+
priority += DEFAULT_PRIORITY
|
|
1846
1774
|
|
|
1847
|
-
if node.prev_nodes and not explicit_priority and not isinstance(node, TriccNodeMainStart):
|
|
1848
|
-
priority = max(priority, *[get_priority(p) for p in node.prev_nodes])
|
|
1849
|
-
|
|
1850
|
-
MAP_PRIORITIES[node.id] = priority
|
|
1851
|
-
|
|
1852
1775
|
return priority
|
|
1853
1776
|
|
|
1854
1777
|
# Sort in place, highest priority first
|
|
@@ -2044,7 +1967,7 @@ def get_prev_instance_skip_expression(node, processed_nodes, process, expression
|
|
|
2044
1967
|
|
|
2045
1968
|
# end def
|
|
2046
1969
|
def get_process_skip_expression(node, processed_nodes, process, expression=None):
|
|
2047
|
-
list_ends =
|
|
1970
|
+
list_ends = OrderedSet(filter(lambda x: issubclass(x.__class__, TriccNodeEnd), processed_nodes))
|
|
2048
1971
|
if list_ends:
|
|
2049
1972
|
end_expressions = []
|
|
2050
1973
|
f_end_expression = get_end_expression(list_ends)
|
|
@@ -2053,11 +1976,8 @@ def get_process_skip_expression(node, processed_nodes, process, expression=None)
|
|
|
2053
1976
|
b_end_expression = get_end_expression(list_ends, "pause")
|
|
2054
1977
|
if b_end_expression:
|
|
2055
1978
|
end_expressions.append(b_end_expression)
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
process_index = PROCESSES.index(process[0])
|
|
2059
|
-
if process_index is not None:
|
|
2060
|
-
for p in PROCESSES[process_index + 1:]:
|
|
1979
|
+
if process[0] in PROCESSES:
|
|
1980
|
+
for p in PROCESSES[PROCESSES.index(process[0]) + 1:]:
|
|
2061
1981
|
p_end_expression = get_end_expression(list_ends, p)
|
|
2062
1982
|
if p_end_expression:
|
|
2063
1983
|
end_expressions.append(p_end_expression)
|
|
@@ -2104,7 +2024,7 @@ def get_accept_diagnostic_node(code, display, severity, priority, activity):
|
|
|
2104
2024
|
return node
|
|
2105
2025
|
|
|
2106
2026
|
|
|
2107
|
-
def get_diagnostic_node(code, display, severity, priority, activity
|
|
2027
|
+
def get_diagnostic_node(code, display, severity, priority, activity):
|
|
2108
2028
|
node = TriccNodeCalculate(
|
|
2109
2029
|
id=generate_id("final." + code),
|
|
2110
2030
|
name="final." + code,
|
|
@@ -2115,7 +2035,7 @@ def get_diagnostic_node(code, display, severity, priority, activity, option):
|
|
|
2115
2035
|
expression_reference=or_join(
|
|
2116
2036
|
[
|
|
2117
2037
|
TriccOperation(TriccOperator.ISTRUE, [TriccReference("pre_final." + code)]),
|
|
2118
|
-
TriccOperation(TriccOperator.SELECTED, [TriccReference("tricc.manual.diag"), TriccStatic(
|
|
2038
|
+
TriccOperation(TriccOperator.SELECTED, [TriccReference("tricc.manual.diag"), TriccStatic(code)]),
|
|
2119
2039
|
]
|
|
2120
2040
|
),
|
|
2121
2041
|
)
|
|
@@ -2174,19 +2094,9 @@ def create_determine_diagnosis_activity(diags):
|
|
|
2174
2094
|
group=activity,
|
|
2175
2095
|
required=TriccStatic(False),
|
|
2176
2096
|
)
|
|
2177
|
-
options = []
|
|
2178
2097
|
for proposed in diags:
|
|
2179
|
-
option = TriccNodeSelectOption(
|
|
2180
|
-
id=generate_id(proposed.name),
|
|
2181
|
-
name=proposed.name,
|
|
2182
|
-
label=proposed.label,
|
|
2183
|
-
list_name=f.list_name,
|
|
2184
|
-
relevance=proposed.activity.applicability,
|
|
2185
|
-
select=f,
|
|
2186
|
-
)
|
|
2187
|
-
options.append(option)
|
|
2188
2098
|
d = get_accept_diagnostic_node(proposed.name, proposed.label, proposed.severity, proposed.priority, activity)
|
|
2189
|
-
c = get_diagnostic_node(proposed.name, proposed.label, proposed.severity, proposed.priority, activity
|
|
2099
|
+
c = get_diagnostic_node(proposed.name, proposed.label, proposed.severity, proposed.priority, activity)
|
|
2190
2100
|
diags_conf.append(d)
|
|
2191
2101
|
r = TriccNodeRhombus(
|
|
2192
2102
|
path=start,
|
|
@@ -2211,6 +2121,17 @@ def create_determine_diagnosis_activity(diags):
|
|
|
2211
2121
|
activity.nodes[wait2.id] = wait2
|
|
2212
2122
|
# fallback
|
|
2213
2123
|
|
|
2124
|
+
options = [
|
|
2125
|
+
TriccNodeSelectOption(
|
|
2126
|
+
id=generate_id(d.name),
|
|
2127
|
+
name=d.name,
|
|
2128
|
+
label=d.label,
|
|
2129
|
+
list_name=f.list_name,
|
|
2130
|
+
relevance=d.activity.applicability,
|
|
2131
|
+
select=f,
|
|
2132
|
+
)
|
|
2133
|
+
for d in diags
|
|
2134
|
+
]
|
|
2214
2135
|
f.options = dict(zip(range(0, len(options)), options))
|
|
2215
2136
|
activity.nodes[f.id] = f
|
|
2216
2137
|
set_prev_next_node(f, end, edge_only=False)
|
|
@@ -2236,9 +2157,7 @@ def get_prev_node_expression(node, processed_nodes, get_overall_exp=False, exclu
|
|
|
2236
2157
|
|
|
2237
2158
|
for act_id in prev_activities:
|
|
2238
2159
|
act_expression_inputs = []
|
|
2239
|
-
none_sequence_defined_prev_node = False
|
|
2240
2160
|
for prev_node in prev_activities[act_id]:
|
|
2241
|
-
none_sequence_defined_prev_node = none_sequence_defined_prev_node or not prev_node.is_sequence_defined
|
|
2242
2161
|
if (
|
|
2243
2162
|
excluded_name is None
|
|
2244
2163
|
or prev_node != excluded_name
|
|
@@ -2265,7 +2184,8 @@ def get_prev_node_expression(node, processed_nodes, get_overall_exp=False, exclu
|
|
|
2265
2184
|
if act_expression_inputs:
|
|
2266
2185
|
act_sub = or_join(act_expression_inputs)
|
|
2267
2186
|
# if there is condition fallback on the calling activity condition
|
|
2268
|
-
|
|
2187
|
+
if act_sub == TriccStatic(True):
|
|
2188
|
+
act_sub = get_node_expression(
|
|
2269
2189
|
prev_node.activity,
|
|
2270
2190
|
processed_nodes=processed_nodes,
|
|
2271
2191
|
get_overall_exp=get_overall_exp,
|
|
@@ -2273,25 +2193,6 @@ def get_prev_node_expression(node, processed_nodes, get_overall_exp=False, exclu
|
|
|
2273
2193
|
negate=False,
|
|
2274
2194
|
process=process,
|
|
2275
2195
|
)
|
|
2276
|
-
if act_sub == TriccStatic(True):
|
|
2277
|
-
act_sub = act_relevance
|
|
2278
|
-
elif act_relevance != TriccStatic(True) and none_sequence_defined_prev_node:
|
|
2279
|
-
# For nodes with is_sequence_defined = False, AND the activity relevance with the prev expression
|
|
2280
|
-
# activity_relevance = get_node_expression(
|
|
2281
|
-
# prev_node.activity,
|
|
2282
|
-
# processed_nodes=processed_nodes,
|
|
2283
|
-
# get_overall_exp=get_overall_exp,
|
|
2284
|
-
# is_prev=True,
|
|
2285
|
-
# negate=False,
|
|
2286
|
-
# process=process,
|
|
2287
|
-
# )
|
|
2288
|
-
act_sub = and_join([
|
|
2289
|
-
TriccOperation(
|
|
2290
|
-
TriccOperator.ISTRUE,
|
|
2291
|
-
[prev_node.activity.root]
|
|
2292
|
-
),
|
|
2293
|
-
act_sub
|
|
2294
|
-
])
|
|
2295
2196
|
add_sub_expression(expression_inputs, act_sub)
|
|
2296
2197
|
# avoid void is there is not conditions to avoid looping too much itme
|
|
2297
2198
|
# expression_inputs = clean_or_list(
|
|
@@ -2338,27 +2239,10 @@ def get_count_terms(node, processed_nodes, get_overall_exp, negate=False, proces
|
|
|
2338
2239
|
return TriccOperation(TriccOperator.PLUS, [TriccOperation(TriccOperator.CAST_NUMBER, [term]) for term in terms])
|
|
2339
2240
|
|
|
2340
2241
|
|
|
2341
|
-
def get_none_option(node):
|
|
2342
|
-
if hasattr(node, "options"):
|
|
2343
|
-
for opt in node.options.values():
|
|
2344
|
-
if opt.name == "opt_none":
|
|
2345
|
-
return opt
|
|
2346
|
-
return None
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
2242
|
def get_count_terms_details(prev_node, processed_nodes, get_overall_exp, negate=False, process=None):
|
|
2350
|
-
|
|
2351
|
-
if opt_none:
|
|
2352
|
-
if isinstance(opt_none, str):
|
|
2353
|
-
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic(opt_none)])
|
|
2354
|
-
elif issubclass(opt_none.__class__, TriccBaseModel):
|
|
2355
|
-
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, opt_none])
|
|
2356
|
-
else:
|
|
2357
|
-
logger.critical(f"unexpected none option value {opt_none}")
|
|
2358
|
-
else:
|
|
2359
|
-
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic("opt_none")])
|
|
2243
|
+
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic("opt_none")])
|
|
2360
2244
|
if isinstance(prev_node, TriccNodeSelectYesNo):
|
|
2361
|
-
return TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic(prev_node.options[0])])
|
|
2245
|
+
return TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic(prev_node.options[0].name)])
|
|
2362
2246
|
elif issubclass(prev_node.__class__, TriccNodeSelect):
|
|
2363
2247
|
if negate:
|
|
2364
2248
|
return
|
|
@@ -2408,11 +2292,7 @@ def get_count_terms_details(prev_node, processed_nodes, get_overall_exp, negate=
|
|
|
2408
2292
|
TriccOperator.CAST_NUMBER,
|
|
2409
2293
|
[
|
|
2410
2294
|
get_node_expression(
|
|
2411
|
-
prev_node,
|
|
2412
|
-
processed_nodes=processed_nodes,
|
|
2413
|
-
get_overall_exp=get_overall_exp,
|
|
2414
|
-
is_prev=True,
|
|
2415
|
-
process=process
|
|
2295
|
+
prev_node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, is_prev=True, process=process
|
|
2416
2296
|
)
|
|
2417
2297
|
],
|
|
2418
2298
|
)
|
|
@@ -2603,6 +2483,15 @@ def get_calculation_terms(node, processed_nodes, get_overall_exp=False, negate=F
|
|
|
2603
2483
|
|
|
2604
2484
|
if isinstance(node.expression_reference, (TriccOperation, TriccStatic)):
|
|
2605
2485
|
expression = node.expression_reference
|
|
2486
|
+
elif node.reference is not None and node.expression_reference is not None:
|
|
2487
|
+
expression = get_prev_node_expression(
|
|
2488
|
+
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, process=process
|
|
2489
|
+
)
|
|
2490
|
+
ref_expression = node.expression_reference.format(*[get_export_name(ref) for ref in node.reference])
|
|
2491
|
+
if expression is not None and expression != "":
|
|
2492
|
+
expression = and_join([expression, ref_expression])
|
|
2493
|
+
else:
|
|
2494
|
+
expression = ref_expression
|
|
2606
2495
|
elif expression is None:
|
|
2607
2496
|
expression = get_prev_node_expression(
|
|
2608
2497
|
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, process=process
|
|
@@ -2665,13 +2554,16 @@ def get_selected_option_expression_single(option_node, negate):
|
|
|
2665
2554
|
|
|
2666
2555
|
def get_selected_option_expression_multiple(option_node, negate):
|
|
2667
2556
|
|
|
2668
|
-
selected = TriccOperation(TriccOperator.SELECTED, [option_node.select,
|
|
2557
|
+
selected = TriccOperation(TriccOperator.SELECTED, [option_node.select, option_node])
|
|
2669
2558
|
|
|
2670
2559
|
if negate:
|
|
2671
|
-
return
|
|
2560
|
+
return TriccOperation(
|
|
2561
|
+
operator=TriccOperator.AND,
|
|
2562
|
+
resource=[
|
|
2672
2563
|
TriccOperation(operator=TriccOperator.NOT, resource=[selected]),
|
|
2673
2564
|
TriccOperation(operator=TriccOperator.ISNOTNULL, resource=[option_node.select]),
|
|
2674
|
-
]
|
|
2565
|
+
],
|
|
2566
|
+
)
|
|
2675
2567
|
|
|
2676
2568
|
else:
|
|
2677
2569
|
return selected
|
|
@@ -2692,12 +2584,6 @@ def generate_calculate(node, processed_nodes, **kwargs):
|
|
|
2692
2584
|
if node not in processed_nodes:
|
|
2693
2585
|
if kwargs.get("warn", True):
|
|
2694
2586
|
logger.debug("generation of calculate for node {}".format(node.get_name()))
|
|
2695
|
-
|
|
2696
|
-
# Set is_sequence_defined for calculate nodes based on dependencies
|
|
2697
|
-
if issubclass(node.__class__, TriccNodeCalculateBase):
|
|
2698
|
-
# Calculate node is sequence defined if ALL prev_nodes have is_sequence_defined = True
|
|
2699
|
-
node.is_sequence_defined = all(prev_node.is_sequence_defined for prev_node in node.prev_nodes)
|
|
2700
|
-
|
|
2701
2587
|
if (
|
|
2702
2588
|
hasattr(node, "expression")
|
|
2703
2589
|
and (node.expression is None)
|
|
@@ -2738,26 +2624,24 @@ def generate_base(node, processed_nodes, **kwargs):
|
|
|
2738
2624
|
# we don't overright if define in the diagram
|
|
2739
2625
|
if node.constraint is None:
|
|
2740
2626
|
if isinstance(node, TriccNodeSelectMultiple):
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
) # '.=\'opt_none\' or not(selected(.,\'opt_none\'))'
|
|
2760
|
-
node.constraint_message = "**None** cannot be selected together with choice."
|
|
2627
|
+
node.constraint = or_join(
|
|
2628
|
+
[
|
|
2629
|
+
TriccOperation(
|
|
2630
|
+
TriccOperator.EQUAL,
|
|
2631
|
+
["$this", TriccStatic("opt_none")],
|
|
2632
|
+
),
|
|
2633
|
+
TriccOperation(
|
|
2634
|
+
TriccOperator.NOT,
|
|
2635
|
+
[
|
|
2636
|
+
TriccOperation(
|
|
2637
|
+
TriccOperator.SELECTED,
|
|
2638
|
+
["$this", TriccStatic("opt_none")],
|
|
2639
|
+
)
|
|
2640
|
+
],
|
|
2641
|
+
),
|
|
2642
|
+
]
|
|
2643
|
+
) # '.=\'opt_none\' or not(selected(.,\'opt_none\'))'
|
|
2644
|
+
node.constraint_message = "**None** cannot be selected together with choice."
|
|
2761
2645
|
elif node.tricc_type in (
|
|
2762
2646
|
TriccNodeType.integer,
|
|
2763
2647
|
TriccNodeType.decimal,
|
|
@@ -2782,7 +2666,7 @@ def generate_base(node, processed_nodes, **kwargs):
|
|
|
2782
2666
|
)
|
|
2783
2667
|
constraints_max = "The maximum value is {0}.".format(node.max)
|
|
2784
2668
|
if len(constraints) > 1:
|
|
2785
|
-
node.constraint =
|
|
2669
|
+
node.constraint = TriccOperation(TriccOperator.AND, constraints)
|
|
2786
2670
|
node.constraint_message = (constraints_min + " " + constraints_max).strip()
|
|
2787
2671
|
elif len(constraints) == 1:
|
|
2788
2672
|
node.constraint = constraints[0]
|