tricc-oo 1.6.26__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 +112 -204
- {tricc_oo-1.6.26.dist-info → tricc_oo-1.7.0.dev1.dist-info}/METADATA +1 -1
- {tricc_oo-1.6.26.dist-info → tricc_oo-1.7.0.dev1.dist-info}/RECORD +22 -21
- {tricc_oo-1.6.26.dist-info → tricc_oo-1.7.0.dev1.dist-info}/WHEEL +1 -1
- {tricc_oo-1.6.26.dist-info → tricc_oo-1.7.0.dev1.dist-info}/licenses/LICENSE +0 -0
- {tricc_oo-1.6.26.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_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,20 +195,18 @@ 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
|
-
def
|
|
201
|
+
def merge_expression(expression, last_version):
|
|
220
202
|
datatype = expression.get_datatype()
|
|
221
203
|
if datatype == "boolean":
|
|
222
|
-
expression = or_join([TriccOperation(TriccOperator.ISTRUE, [last_version
|
|
204
|
+
expression = or_join([TriccOperation(TriccOperator.ISTRUE, [last_version]), expression])
|
|
223
205
|
|
|
224
206
|
elif datatype == "number":
|
|
225
|
-
expression = TriccOperation(TriccOperator.PLUS, [last_version,
|
|
207
|
+
expression = TriccOperation(TriccOperator.PLUS, [last_version, expression])
|
|
226
208
|
else:
|
|
227
|
-
expression = TriccOperation(TriccOperator.COALESCE, [
|
|
209
|
+
expression = TriccOperation(TriccOperator.COALESCE, [last_version, expression])
|
|
228
210
|
return expression
|
|
229
211
|
|
|
230
212
|
|
|
@@ -251,14 +233,8 @@ def load_calculate(
|
|
|
251
233
|
# tricc diagnostic have the same name as proposed diag but will be serialised with different names
|
|
252
234
|
|
|
253
235
|
last_version = set_last_version_false(node, processed_nodes)
|
|
254
|
-
# Get all previous versions from processed_nodes, not just the last one
|
|
255
|
-
node_name = node.name if not isinstance(node, TriccNodeEnd) else node.get_reference()
|
|
256
|
-
all_prev_versions = get_versions(node_name, processed_nodes)
|
|
257
|
-
# Exclude the current node itself
|
|
258
|
-
all_prev_versions = [v for v in all_prev_versions if v != node]
|
|
259
|
-
|
|
260
236
|
if last_version:
|
|
261
|
-
get_version_inheritance(node,
|
|
237
|
+
last_version = get_version_inheritance(node, last_version, processed_nodes)
|
|
262
238
|
|
|
263
239
|
generate_calculates(node, calculates, used_calculates, processed_nodes=processed_nodes, process=process)
|
|
264
240
|
|
|
@@ -426,11 +402,6 @@ def get_bridge_path(prev_nodes, node=None, edge_only=False):
|
|
|
426
402
|
calc = TriccNodeDisplayBridge(**data)
|
|
427
403
|
else:
|
|
428
404
|
calc = TriccNodeBridge(**data)
|
|
429
|
-
if node:
|
|
430
|
-
priority = getattr(node, 'priority', None)
|
|
431
|
-
if priority:
|
|
432
|
-
calc.priority = priority
|
|
433
|
-
|
|
434
405
|
return calc
|
|
435
406
|
|
|
436
407
|
|
|
@@ -558,7 +529,7 @@ def generate_calculates(node, calculates, used_calculates, processed_nodes, proc
|
|
|
558
529
|
node.activity.calculates.append(calc_node)
|
|
559
530
|
last_version = set_last_version_false(calc_node, processed_nodes)
|
|
560
531
|
if last_version:
|
|
561
|
-
calc_node.expression =
|
|
532
|
+
calc_node.expression = merge_expression(calc_node.expression, last_version)
|
|
562
533
|
processed_nodes.add(calc_node)
|
|
563
534
|
logger.debug(
|
|
564
535
|
"generate_save_calculate:{}:{} as {}".format(
|
|
@@ -591,7 +562,7 @@ def generate_calculates(node, calculates, used_calculates, processed_nodes, proc
|
|
|
591
562
|
node.activity.calculates.append(calc_node)
|
|
592
563
|
last_version = set_last_version_false(calc_node, processed_nodes)
|
|
593
564
|
if last_version:
|
|
594
|
-
calc_node.expression =
|
|
565
|
+
calc_node.expression = merge_expression(calc_node.expression, last_version)
|
|
595
566
|
processed_nodes.add(calc_node)
|
|
596
567
|
list_calc.append(calc_node)
|
|
597
568
|
node.activity.nodes[calc_node.id] = calc_node
|
|
@@ -831,7 +802,7 @@ def process_operation_reference(
|
|
|
831
802
|
operation,
|
|
832
803
|
node,
|
|
833
804
|
processed_nodes,
|
|
834
|
-
calculates
|
|
805
|
+
calculates,
|
|
835
806
|
used_calculates=None,
|
|
836
807
|
replace_reference=False,
|
|
837
808
|
warn=False,
|
|
@@ -994,7 +965,6 @@ def walktrhough_tricc_node_processed_stached(
|
|
|
994
965
|
warn=False,
|
|
995
966
|
node_path=[],
|
|
996
967
|
process=None,
|
|
997
|
-
loop_count=0,
|
|
998
968
|
**kwargs,
|
|
999
969
|
):
|
|
1000
970
|
ended_activity = False
|
|
@@ -1160,10 +1130,7 @@ def walktrhough_tricc_node_processed_stached(
|
|
|
1160
1130
|
if nn not in stashed_nodes:
|
|
1161
1131
|
stashed_nodes.insert_at_top(nn)
|
|
1162
1132
|
if not recursive:
|
|
1163
|
-
|
|
1164
|
-
if _last_reordered_group != node.group:
|
|
1165
|
-
reorder_node_list(stashed_nodes, node.group, processed_nodes)
|
|
1166
|
-
_last_reordered_group = node.group
|
|
1133
|
+
reorder_node_list(stashed_nodes, node.group, processed_nodes)
|
|
1167
1134
|
|
|
1168
1135
|
else:
|
|
1169
1136
|
if prev_process and process and prev_process != process[0]:
|
|
@@ -1310,7 +1277,7 @@ def stashed_node_func(node, callback, recursive=False, **kwargs):
|
|
|
1310
1277
|
|
|
1311
1278
|
|
|
1312
1279
|
# check if the all the prev nodes are processed
|
|
1313
|
-
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):
|
|
1314
1281
|
if isinstance(in_node, TriccNodeSelectOption):
|
|
1315
1282
|
node = in_node.select
|
|
1316
1283
|
elif isinstance(in_node, (TriccNodeActivityStart, TriccNodeMainStart)):
|
|
@@ -1321,38 +1288,36 @@ def is_ready_to_process(in_node, processed_nodes, strict=True, local=False, loop
|
|
|
1321
1288
|
if hasattr(node, "prev_nodes"):
|
|
1322
1289
|
# ensure the previous node of the select are processed, not the option prev nodes
|
|
1323
1290
|
for prev_node in node.prev_nodes:
|
|
1324
|
-
if is_prev_processed(prev_node, node, processed_nodes, local
|
|
1291
|
+
if is_prev_processed(prev_node, node, processed_nodes, local) is False:
|
|
1325
1292
|
return False
|
|
1326
1293
|
return True
|
|
1327
1294
|
|
|
1328
1295
|
|
|
1329
|
-
def is_prev_processed(prev_node, node, processed_nodes, local
|
|
1296
|
+
def is_prev_processed(prev_node, node, processed_nodes, local):
|
|
1330
1297
|
if hasattr(prev_node, "select"):
|
|
1331
|
-
return is_prev_processed(prev_node.select, node, processed_nodes, local
|
|
1298
|
+
return is_prev_processed(prev_node.select, node, processed_nodes, local)
|
|
1332
1299
|
if prev_node not in processed_nodes and (not local):
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
"is_ready_to_process:failed:via_excl: {} - {} > {} {}:{}".format(
|
|
1340
|
-
get_data_for_log(p_n_node), prev_node.get_name(), node.__class__, node.get_name(), node.instance
|
|
1341
|
-
)
|
|
1342
|
-
)
|
|
1343
|
-
|
|
1344
|
-
else:
|
|
1345
|
-
logger.debug(
|
|
1346
|
-
"is_ready_to_process:failed: {} -> {} {}:{}".format(
|
|
1347
|
-
get_data_for_log(prev_node), node.__class__, node.get_name(), node.instance
|
|
1348
|
-
)
|
|
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
|
|
1349
1306
|
)
|
|
1307
|
+
)
|
|
1350
1308
|
|
|
1309
|
+
else:
|
|
1351
1310
|
logger.debug(
|
|
1352
|
-
"
|
|
1353
|
-
prev_node.__class__,
|
|
1311
|
+
"is_ready_to_process:failed: {} -> {} {}:{}".format(
|
|
1312
|
+
get_data_for_log(prev_node), node.__class__, node.get_name(), node.instance
|
|
1354
1313
|
)
|
|
1355
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
|
+
)
|
|
1356
1321
|
return False
|
|
1357
1322
|
return True
|
|
1358
1323
|
|
|
@@ -1767,36 +1732,28 @@ def replace_next_node(prev_node, next_node, old_node):
|
|
|
1767
1732
|
|
|
1768
1733
|
|
|
1769
1734
|
# Priority constants
|
|
1770
|
-
SAME_GROUP_PRIORITY =
|
|
1771
|
-
PARENT_GROUP_PRIORITY =
|
|
1772
|
-
ACTIVE_ACTIVITY_PRIORITY =
|
|
1773
|
-
NON_START_ACTIVITY_PRIORITY =
|
|
1774
|
-
ACTIVE_ACTIVITY_LOWER_PRIORITY =
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
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
|
+
|
|
1779
1744
|
def reorder_node_list(node_list, group, processed_nodes):
|
|
1780
1745
|
# Cache active activities for O(1) lookup
|
|
1781
1746
|
active_activities = {n.activity for n in processed_nodes}
|
|
1782
|
-
MAP_PRIORITIES = {}
|
|
1783
|
-
def get_priority(node):
|
|
1784
|
-
if node.id in MAP_PRIORITIES:
|
|
1785
|
-
return MAP_PRIORITIES[node.id]
|
|
1786
|
-
if isinstance(node, (TriccNodeActivityStart, TriccNodeMainStart)):
|
|
1787
|
-
return get_priority(node.activity)
|
|
1788
|
-
if isinstance(node, (TriccNodeSelectOption)):
|
|
1789
|
-
return get_priority(node.select)
|
|
1790
1747
|
|
|
1748
|
+
def get_priority(node):
|
|
1791
1749
|
# Cache attributes to avoid repeated getattr calls
|
|
1792
|
-
|
|
1793
|
-
priority = int(explicit_priority or 0)
|
|
1750
|
+
priority = int(getattr(node, "priority", 0) or 0)
|
|
1794
1751
|
node_group = getattr(node, "group", None)
|
|
1795
1752
|
activity = getattr(node, "activity", None)
|
|
1796
1753
|
|
|
1797
1754
|
# Check for same group
|
|
1798
1755
|
if group is not None and node_group and node_group.id == group.id:
|
|
1799
|
-
priority += SAME_GROUP_PRIORITY
|
|
1756
|
+
priority += SAME_GROUP_PRIORITY
|
|
1800
1757
|
# Check for parent group
|
|
1801
1758
|
elif hasattr(group, "group") and group.group and node_group and node_group.id == group.group.id:
|
|
1802
1759
|
priority += PARENT_GROUP_PRIORITY
|
|
@@ -1810,21 +1767,11 @@ def reorder_node_list(node_list, group, processed_nodes):
|
|
|
1810
1767
|
elif activity and activity in active_activities:
|
|
1811
1768
|
priority += ACTIVE_ACTIVITY_LOWER_PRIORITY
|
|
1812
1769
|
# Check for rhombus nodes
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
if (
|
|
1816
|
-
issubclass(node.__class__, TriccNodeDisplayCalculateBase) or
|
|
1817
|
-
isinstance(node, TriccNodeEnd)
|
|
1818
|
-
) and not isinstance(node, TriccNodeActivityEnd) and hasattr(node, 'prev_nodes') and len(node.prev_nodes) > 0:
|
|
1819
|
-
priority += FLOW_CALCULATE_NODE_PRIORITY_TOP_UP
|
|
1820
1770
|
elif issubclass(node.__class__, TriccRhombusMixIn):
|
|
1821
|
-
priority +=
|
|
1771
|
+
priority += RHOMBUS_PRIORITY
|
|
1772
|
+
else:
|
|
1773
|
+
priority += DEFAULT_PRIORITY
|
|
1822
1774
|
|
|
1823
|
-
if node.prev_nodes and not explicit_priority and not isinstance(node, TriccNodeMainStart):
|
|
1824
|
-
priority = max(priority, *[get_priority(p) for p in node.prev_nodes])
|
|
1825
|
-
|
|
1826
|
-
MAP_PRIORITIES[node.id] = priority
|
|
1827
|
-
|
|
1828
1775
|
return priority
|
|
1829
1776
|
|
|
1830
1777
|
# Sort in place, highest priority first
|
|
@@ -2020,7 +1967,7 @@ def get_prev_instance_skip_expression(node, processed_nodes, process, expression
|
|
|
2020
1967
|
|
|
2021
1968
|
# end def
|
|
2022
1969
|
def get_process_skip_expression(node, processed_nodes, process, expression=None):
|
|
2023
|
-
list_ends =
|
|
1970
|
+
list_ends = OrderedSet(filter(lambda x: issubclass(x.__class__, TriccNodeEnd), processed_nodes))
|
|
2024
1971
|
if list_ends:
|
|
2025
1972
|
end_expressions = []
|
|
2026
1973
|
f_end_expression = get_end_expression(list_ends)
|
|
@@ -2029,11 +1976,8 @@ def get_process_skip_expression(node, processed_nodes, process, expression=None)
|
|
|
2029
1976
|
b_end_expression = get_end_expression(list_ends, "pause")
|
|
2030
1977
|
if b_end_expression:
|
|
2031
1978
|
end_expressions.append(b_end_expression)
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
process_index = PROCESSES.index(process[0])
|
|
2035
|
-
if process_index is not None:
|
|
2036
|
-
for p in PROCESSES[process_index + 1:]:
|
|
1979
|
+
if process[0] in PROCESSES:
|
|
1980
|
+
for p in PROCESSES[PROCESSES.index(process[0]) + 1:]:
|
|
2037
1981
|
p_end_expression = get_end_expression(list_ends, p)
|
|
2038
1982
|
if p_end_expression:
|
|
2039
1983
|
end_expressions.append(p_end_expression)
|
|
@@ -2080,7 +2024,7 @@ def get_accept_diagnostic_node(code, display, severity, priority, activity):
|
|
|
2080
2024
|
return node
|
|
2081
2025
|
|
|
2082
2026
|
|
|
2083
|
-
def get_diagnostic_node(code, display, severity, priority, activity
|
|
2027
|
+
def get_diagnostic_node(code, display, severity, priority, activity):
|
|
2084
2028
|
node = TriccNodeCalculate(
|
|
2085
2029
|
id=generate_id("final." + code),
|
|
2086
2030
|
name="final." + code,
|
|
@@ -2091,7 +2035,7 @@ def get_diagnostic_node(code, display, severity, priority, activity, option):
|
|
|
2091
2035
|
expression_reference=or_join(
|
|
2092
2036
|
[
|
|
2093
2037
|
TriccOperation(TriccOperator.ISTRUE, [TriccReference("pre_final." + code)]),
|
|
2094
|
-
TriccOperation(TriccOperator.SELECTED, [TriccReference("tricc.manual.diag"), TriccStatic(
|
|
2038
|
+
TriccOperation(TriccOperator.SELECTED, [TriccReference("tricc.manual.diag"), TriccStatic(code)]),
|
|
2095
2039
|
]
|
|
2096
2040
|
),
|
|
2097
2041
|
)
|
|
@@ -2150,19 +2094,9 @@ def create_determine_diagnosis_activity(diags):
|
|
|
2150
2094
|
group=activity,
|
|
2151
2095
|
required=TriccStatic(False),
|
|
2152
2096
|
)
|
|
2153
|
-
options = []
|
|
2154
2097
|
for proposed in diags:
|
|
2155
|
-
option = TriccNodeSelectOption(
|
|
2156
|
-
id=generate_id(proposed.name),
|
|
2157
|
-
name=proposed.name,
|
|
2158
|
-
label=proposed.label,
|
|
2159
|
-
list_name=f.list_name,
|
|
2160
|
-
relevance=proposed.activity.applicability,
|
|
2161
|
-
select=f,
|
|
2162
|
-
)
|
|
2163
|
-
options.append(option)
|
|
2164
2098
|
d = get_accept_diagnostic_node(proposed.name, proposed.label, proposed.severity, proposed.priority, activity)
|
|
2165
|
-
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)
|
|
2166
2100
|
diags_conf.append(d)
|
|
2167
2101
|
r = TriccNodeRhombus(
|
|
2168
2102
|
path=start,
|
|
@@ -2187,6 +2121,17 @@ def create_determine_diagnosis_activity(diags):
|
|
|
2187
2121
|
activity.nodes[wait2.id] = wait2
|
|
2188
2122
|
# fallback
|
|
2189
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
|
+
]
|
|
2190
2135
|
f.options = dict(zip(range(0, len(options)), options))
|
|
2191
2136
|
activity.nodes[f.id] = f
|
|
2192
2137
|
set_prev_next_node(f, end, edge_only=False)
|
|
@@ -2212,9 +2157,7 @@ def get_prev_node_expression(node, processed_nodes, get_overall_exp=False, exclu
|
|
|
2212
2157
|
|
|
2213
2158
|
for act_id in prev_activities:
|
|
2214
2159
|
act_expression_inputs = []
|
|
2215
|
-
none_sequence_defined_prev_node = False
|
|
2216
2160
|
for prev_node in prev_activities[act_id]:
|
|
2217
|
-
none_sequence_defined_prev_node = none_sequence_defined_prev_node or not prev_node.is_sequence_defined
|
|
2218
2161
|
if (
|
|
2219
2162
|
excluded_name is None
|
|
2220
2163
|
or prev_node != excluded_name
|
|
@@ -2241,7 +2184,8 @@ def get_prev_node_expression(node, processed_nodes, get_overall_exp=False, exclu
|
|
|
2241
2184
|
if act_expression_inputs:
|
|
2242
2185
|
act_sub = or_join(act_expression_inputs)
|
|
2243
2186
|
# if there is condition fallback on the calling activity condition
|
|
2244
|
-
|
|
2187
|
+
if act_sub == TriccStatic(True):
|
|
2188
|
+
act_sub = get_node_expression(
|
|
2245
2189
|
prev_node.activity,
|
|
2246
2190
|
processed_nodes=processed_nodes,
|
|
2247
2191
|
get_overall_exp=get_overall_exp,
|
|
@@ -2249,25 +2193,6 @@ def get_prev_node_expression(node, processed_nodes, get_overall_exp=False, exclu
|
|
|
2249
2193
|
negate=False,
|
|
2250
2194
|
process=process,
|
|
2251
2195
|
)
|
|
2252
|
-
if act_sub == TriccStatic(True):
|
|
2253
|
-
act_sub = act_relevance
|
|
2254
|
-
elif act_relevance != TriccStatic(True) and none_sequence_defined_prev_node:
|
|
2255
|
-
# For nodes with is_sequence_defined = False, AND the activity relevance with the prev expression
|
|
2256
|
-
# activity_relevance = get_node_expression(
|
|
2257
|
-
# prev_node.activity,
|
|
2258
|
-
# processed_nodes=processed_nodes,
|
|
2259
|
-
# get_overall_exp=get_overall_exp,
|
|
2260
|
-
# is_prev=True,
|
|
2261
|
-
# negate=False,
|
|
2262
|
-
# process=process,
|
|
2263
|
-
# )
|
|
2264
|
-
act_sub = and_join([
|
|
2265
|
-
TriccOperation(
|
|
2266
|
-
TriccOperator.ISTRUE,
|
|
2267
|
-
[prev_node.activity.root]
|
|
2268
|
-
),
|
|
2269
|
-
act_sub
|
|
2270
|
-
])
|
|
2271
2196
|
add_sub_expression(expression_inputs, act_sub)
|
|
2272
2197
|
# avoid void is there is not conditions to avoid looping too much itme
|
|
2273
2198
|
# expression_inputs = clean_or_list(
|
|
@@ -2314,27 +2239,10 @@ def get_count_terms(node, processed_nodes, get_overall_exp, negate=False, proces
|
|
|
2314
2239
|
return TriccOperation(TriccOperator.PLUS, [TriccOperation(TriccOperator.CAST_NUMBER, [term]) for term in terms])
|
|
2315
2240
|
|
|
2316
2241
|
|
|
2317
|
-
def get_none_option(node):
|
|
2318
|
-
if hasattr(node, "options"):
|
|
2319
|
-
for opt in node.options.values():
|
|
2320
|
-
if opt.name == "opt_none":
|
|
2321
|
-
return opt
|
|
2322
|
-
return None
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
2242
|
def get_count_terms_details(prev_node, processed_nodes, get_overall_exp, negate=False, process=None):
|
|
2326
|
-
|
|
2327
|
-
if opt_none:
|
|
2328
|
-
if isinstance(opt_none, str):
|
|
2329
|
-
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic(opt_none)])
|
|
2330
|
-
elif issubclass(opt_none.__class__, TriccBaseModel):
|
|
2331
|
-
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, opt_none])
|
|
2332
|
-
else:
|
|
2333
|
-
logger.critical(f"unexpected none option value {opt_none}")
|
|
2334
|
-
else:
|
|
2335
|
-
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic("opt_none")])
|
|
2243
|
+
operation_none = TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic("opt_none")])
|
|
2336
2244
|
if isinstance(prev_node, TriccNodeSelectYesNo):
|
|
2337
|
-
return TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic(prev_node.options[0])])
|
|
2245
|
+
return TriccOperation(TriccOperator.SELECTED, [prev_node, TriccStatic(prev_node.options[0].name)])
|
|
2338
2246
|
elif issubclass(prev_node.__class__, TriccNodeSelect):
|
|
2339
2247
|
if negate:
|
|
2340
2248
|
return
|
|
@@ -2384,11 +2292,7 @@ def get_count_terms_details(prev_node, processed_nodes, get_overall_exp, negate=
|
|
|
2384
2292
|
TriccOperator.CAST_NUMBER,
|
|
2385
2293
|
[
|
|
2386
2294
|
get_node_expression(
|
|
2387
|
-
prev_node,
|
|
2388
|
-
processed_nodes=processed_nodes,
|
|
2389
|
-
get_overall_exp=get_overall_exp,
|
|
2390
|
-
is_prev=True,
|
|
2391
|
-
process=process
|
|
2295
|
+
prev_node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, is_prev=True, process=process
|
|
2392
2296
|
)
|
|
2393
2297
|
],
|
|
2394
2298
|
)
|
|
@@ -2579,6 +2483,15 @@ def get_calculation_terms(node, processed_nodes, get_overall_exp=False, negate=F
|
|
|
2579
2483
|
|
|
2580
2484
|
if isinstance(node.expression_reference, (TriccOperation, TriccStatic)):
|
|
2581
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
|
|
2582
2495
|
elif expression is None:
|
|
2583
2496
|
expression = get_prev_node_expression(
|
|
2584
2497
|
node, processed_nodes=processed_nodes, get_overall_exp=get_overall_exp, process=process
|
|
@@ -2641,13 +2554,16 @@ def get_selected_option_expression_single(option_node, negate):
|
|
|
2641
2554
|
|
|
2642
2555
|
def get_selected_option_expression_multiple(option_node, negate):
|
|
2643
2556
|
|
|
2644
|
-
selected = TriccOperation(TriccOperator.SELECTED, [option_node.select,
|
|
2557
|
+
selected = TriccOperation(TriccOperator.SELECTED, [option_node.select, option_node])
|
|
2645
2558
|
|
|
2646
2559
|
if negate:
|
|
2647
|
-
return
|
|
2560
|
+
return TriccOperation(
|
|
2561
|
+
operator=TriccOperator.AND,
|
|
2562
|
+
resource=[
|
|
2648
2563
|
TriccOperation(operator=TriccOperator.NOT, resource=[selected]),
|
|
2649
2564
|
TriccOperation(operator=TriccOperator.ISNOTNULL, resource=[option_node.select]),
|
|
2650
|
-
]
|
|
2565
|
+
],
|
|
2566
|
+
)
|
|
2651
2567
|
|
|
2652
2568
|
else:
|
|
2653
2569
|
return selected
|
|
@@ -2668,12 +2584,6 @@ def generate_calculate(node, processed_nodes, **kwargs):
|
|
|
2668
2584
|
if node not in processed_nodes:
|
|
2669
2585
|
if kwargs.get("warn", True):
|
|
2670
2586
|
logger.debug("generation of calculate for node {}".format(node.get_name()))
|
|
2671
|
-
|
|
2672
|
-
# Set is_sequence_defined for calculate nodes based on dependencies
|
|
2673
|
-
if issubclass(node.__class__, TriccNodeCalculateBase):
|
|
2674
|
-
# Calculate node is sequence defined if ALL prev_nodes have is_sequence_defined = True
|
|
2675
|
-
node.is_sequence_defined = all(prev_node.is_sequence_defined for prev_node in node.prev_nodes)
|
|
2676
|
-
|
|
2677
2587
|
if (
|
|
2678
2588
|
hasattr(node, "expression")
|
|
2679
2589
|
and (node.expression is None)
|
|
@@ -2714,26 +2624,24 @@ def generate_base(node, processed_nodes, **kwargs):
|
|
|
2714
2624
|
# we don't overright if define in the diagram
|
|
2715
2625
|
if node.constraint is None:
|
|
2716
2626
|
if isinstance(node, TriccNodeSelectMultiple):
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
) # '.=\'opt_none\' or not(selected(.,\'opt_none\'))'
|
|
2736
|
-
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."
|
|
2737
2645
|
elif node.tricc_type in (
|
|
2738
2646
|
TriccNodeType.integer,
|
|
2739
2647
|
TriccNodeType.decimal,
|
|
@@ -2758,7 +2666,7 @@ def generate_base(node, processed_nodes, **kwargs):
|
|
|
2758
2666
|
)
|
|
2759
2667
|
constraints_max = "The maximum value is {0}.".format(node.max)
|
|
2760
2668
|
if len(constraints) > 1:
|
|
2761
|
-
node.constraint =
|
|
2669
|
+
node.constraint = TriccOperation(TriccOperator.AND, constraints)
|
|
2762
2670
|
node.constraint_message = (constraints_min + " " + constraints_max).strip()
|
|
2763
2671
|
elif len(constraints) == 1:
|
|
2764
2672
|
node.constraint = constraints[0]
|