tricc-oo 1.0.1__py3-none-any.whl → 1.4.15__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 +213 -0
- tests/test_cql.py +197 -0
- tests/to_ocl.py +51 -0
- {tricc → tricc_oo}/__init__.py +3 -1
- tricc_oo/converters/codesystem_to_ocl.py +169 -0
- tricc_oo/converters/cql/cqlLexer.py +822 -0
- tricc_oo/converters/cql/cqlListener.py +1632 -0
- tricc_oo/converters/cql/cqlParser.py +11204 -0
- tricc_oo/converters/cql/cqlVisitor.py +913 -0
- tricc_oo/converters/cql_to_operation.py +402 -0
- tricc_oo/converters/datadictionnary.py +115 -0
- tricc_oo/converters/drawio_type_map.py +222 -0
- tricc_oo/converters/tricc_to_xls_form.py +61 -0
- tricc_oo/converters/utils.py +65 -0
- tricc_oo/converters/xml_to_tricc.py +1003 -0
- tricc_oo/models/__init__.py +4 -0
- tricc_oo/models/base.py +732 -0
- tricc_oo/models/calculate.py +216 -0
- tricc_oo/models/ocl.py +281 -0
- tricc_oo/models/ordered_set.py +125 -0
- tricc_oo/models/tricc.py +418 -0
- tricc_oo/parsers/xml.py +138 -0
- tricc_oo/serializers/__init__.py +0 -0
- tricc_oo/serializers/xls_form.py +745 -0
- tricc_oo/strategies/__init__.py +0 -0
- tricc_oo/strategies/input/__init__.py +0 -0
- tricc_oo/strategies/input/base_input_strategy.py +111 -0
- tricc_oo/strategies/input/drawio.py +317 -0
- tricc_oo/strategies/output/base_output_strategy.py +148 -0
- tricc_oo/strategies/output/spice.py +365 -0
- tricc_oo/strategies/output/xls_form.py +697 -0
- tricc_oo/strategies/output/xlsform_cdss.py +189 -0
- tricc_oo/strategies/output/xlsform_cht.py +200 -0
- tricc_oo/strategies/output/xlsform_cht_hf.py +334 -0
- tricc_oo/visitors/__init__.py +0 -0
- tricc_oo/visitors/tricc.py +2198 -0
- tricc_oo/visitors/utils.py +17 -0
- tricc_oo/visitors/xform_pd.py +264 -0
- tricc_oo-1.4.15.dist-info/METADATA +219 -0
- tricc_oo-1.4.15.dist-info/RECORD +46 -0
- {tricc_oo-1.0.1.dist-info → tricc_oo-1.4.15.dist-info}/WHEEL +1 -1
- tricc_oo-1.4.15.dist-info/top_level.txt +2 -0
- tricc/converters/mc_to_tricc.py +0 -542
- tricc/converters/tricc_to_xls_form.py +0 -553
- tricc/converters/utils.py +0 -44
- tricc/converters/xml_to_tricc.py +0 -740
- tricc/models/tricc.py +0 -1093
- tricc/parsers/xml.py +0 -81
- tricc/serializers/xls_form.py +0 -364
- tricc/strategies/input/base_input_strategy.py +0 -80
- tricc/strategies/input/drawio.py +0 -246
- tricc/strategies/input/medalcreator.py +0 -168
- tricc/strategies/output/base_output_strategy.py +0 -92
- tricc/strategies/output/xls_form.py +0 -194
- tricc/strategies/output/xlsform_cdss.py +0 -46
- tricc/strategies/output/xlsform_cht.py +0 -106
- tricc/visitors/tricc.py +0 -375
- tricc_oo-1.0.1.dist-info/LICENSE +0 -78
- tricc_oo-1.0.1.dist-info/METADATA +0 -229
- tricc_oo-1.0.1.dist-info/RECORD +0 -26
- tricc_oo-1.0.1.dist-info/top_level.txt +0 -2
- venv/bin/vba_extract.py +0 -78
- {tricc → tricc_oo}/converters/__init__.py +0 -0
- {tricc → tricc_oo}/models/lang.py +0 -0
- {tricc/serializers → tricc_oo/parsers}/__init__.py +0 -0
- {tricc → tricc_oo}/serializers/planuml.py +0 -0
|
@@ -1,553 +0,0 @@
|
|
|
1
|
-
from operator import attrgetter
|
|
2
|
-
import re
|
|
3
|
-
|
|
4
|
-
from tricc.converters.utils import OPERATION_LIST, clean_str,clean_name
|
|
5
|
-
from tricc.models.tricc import *
|
|
6
|
-
|
|
7
|
-
# from babel import _
|
|
8
|
-
|
|
9
|
-
TRICC_SELECT_MULTIPLE_CALC_EXPRESSION = "count-selected(${{{0}}}) - number(selected(${{{0}}},'opt_none'))"
|
|
10
|
-
TRICC_SELECT_MULTIPLE_CALC_NONE_EXPRESSION = "selected(${{{0}}},'opt_none')"
|
|
11
|
-
TRICC_CALC_EXPRESSION = "${{{0}}}>0"
|
|
12
|
-
TRICC_CALC_NOT_EXPRESSION = "${{{0}}}=0"
|
|
13
|
-
TRICC_EMPTY_EXPRESSION = "coalesce(${{{0}}},'') != ''"
|
|
14
|
-
TRICC_SELECTED_EXPRESSION = 'selected(${{{0}}}, "{1}")'
|
|
15
|
-
TRICC_REF_EXPRESSION = "${{{0}}}"
|
|
16
|
-
TRICC_NEGATE = "not({})"
|
|
17
|
-
TRICC_NUMBER = "number({})"
|
|
18
|
-
TRICC_NAND_EXPRESSION = '({0}) and not({1})'
|
|
19
|
-
TRICC_AND_EXPRESSION = '({0}) and ({1})'
|
|
20
|
-
VERSION_SEPARATOR = '_Vv_'
|
|
21
|
-
INSTANCE_SEPARATOR = "_Ii_"
|
|
22
|
-
|
|
23
|
-
import logging
|
|
24
|
-
|
|
25
|
-
logger = logging.getLogger("default")
|
|
26
|
-
|
|
27
|
-
# gettext language dict {'code':gettext}
|
|
28
|
-
|
|
29
|
-
def generate_xls_form_condition(node, processed_nodes, **kwargs):
|
|
30
|
-
if is_ready_to_process(node, processed_nodes, strict=False):
|
|
31
|
-
if node not in processed_nodes:
|
|
32
|
-
if issubclass(node.__class__, TriccRhombusMixIn) and isinstance(node.reference, str):
|
|
33
|
-
logger.warning("node {} still using the reference string".format(node.get_name()))
|
|
34
|
-
if issubclass(node.__class__, TriccNodeInputModel):
|
|
35
|
-
# we don't overright if define in the diagram
|
|
36
|
-
if node.constraint is None:
|
|
37
|
-
if isinstance(node, TriccNodeSelectMultiple):
|
|
38
|
-
node.constraint = '.=\'opt_none\' or not(selected(.,\'opt_none\'))'
|
|
39
|
-
node.constraint_message = '**None** cannot be selected together with choice.'
|
|
40
|
-
elif node.tricc_type in (TriccNodeType.integer, TriccNodeType.decimal):
|
|
41
|
-
constraints = []
|
|
42
|
-
constraints_min = None
|
|
43
|
-
constraints_max = None
|
|
44
|
-
if node.min is not None:
|
|
45
|
-
constraints.append('.>=' + node.min)
|
|
46
|
-
constraints_min= "The minimun value is {0}.".format(node.min)
|
|
47
|
-
if node.max is not None:
|
|
48
|
-
constraints.append('.>=' + node.max)
|
|
49
|
-
constraints_max="The maximum value is {0}.".format(node.max)
|
|
50
|
-
if len(constraints) > 0:
|
|
51
|
-
node.constraint = ' and '.join(constraints)
|
|
52
|
-
node.constraint_message = (constraints_min + " " + constraints_max).strip()
|
|
53
|
-
# continue walk
|
|
54
|
-
return True
|
|
55
|
-
return False
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def generate_xls_form_relevance(node, processed_nodes, stashed_nodes, **kwargs):
|
|
59
|
-
if is_ready_to_process(node, processed_nodes):
|
|
60
|
-
if node not in processed_nodes:
|
|
61
|
-
logger.debug('Processing relevance for node {0}'.format(node.get_name()))
|
|
62
|
-
# if has prev, create condition
|
|
63
|
-
if hasattr(node, 'relevance') and node.relevance is None:
|
|
64
|
-
node.relevance = get_node_expressions(node, processed_nodes)
|
|
65
|
-
# manage not Available
|
|
66
|
-
if isinstance(node, TriccNodeSelectNotAvailable):
|
|
67
|
-
# update the checkbox
|
|
68
|
-
if len(node.prev_nodes) == 1:
|
|
69
|
-
parent_node = node.prev_nodes[0]
|
|
70
|
-
parent_empty = "${{{0}}}=''".format(get_export_name(parent_node))
|
|
71
|
-
node.relevance = and_join(node.relevance, parent_empty)
|
|
72
|
-
|
|
73
|
-
node.required = parent_empty
|
|
74
|
-
node.constraint = parent_empty
|
|
75
|
-
node.constraint_message = "Cannot be selected with a value entered above"
|
|
76
|
-
# update the check box parent : create loop error
|
|
77
|
-
parent_node.required = None # "${{{0}}}=''".format(node.name)
|
|
78
|
-
else:
|
|
79
|
-
logger.warning("not available node {} does't have a single parent".format(node.get_name()))
|
|
80
|
-
|
|
81
|
-
return True
|
|
82
|
-
return False
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def generate_xls_form_calculate(node, processed_nodes, stashed_nodes, **kwargs):
|
|
86
|
-
if is_ready_to_process(node, processed_nodes):
|
|
87
|
-
if node not in processed_nodes:
|
|
88
|
-
logger.debug("generation of calculate for node {}".format(node.get_name()))
|
|
89
|
-
if hasattr(node, 'expression') and (node.expression is None) and issubclass(node.__class__,TriccNodeCalculateBase):
|
|
90
|
-
node.expression = get_node_expressions(node, processed_nodes)
|
|
91
|
-
# continue walk
|
|
92
|
-
return True
|
|
93
|
-
return False
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
# if the node is "required" then we can take the fact that it has value for the next elements
|
|
97
|
-
def get_required_node_expression(node):
|
|
98
|
-
return TRICC_EMPTY_EXPRESSION.format(get_export_name(node))
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
# Get a selected option
|
|
102
|
-
def get_selected_option_expression(option_node):
|
|
103
|
-
return TRICC_SELECTED_EXPRESSION.format(get_export_name(option_node.select), option_node.name)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
# Function that add element to array is not None or ''
|
|
107
|
-
def add_sub_expression(array, sub):
|
|
108
|
-
if sub is not None and sub not in array and sub != '':
|
|
109
|
-
not_sub = negate_term(sub)
|
|
110
|
-
if not_sub in array:
|
|
111
|
-
# avoid having 2 conditions that are complete opposites
|
|
112
|
-
array.remove(not_sub)
|
|
113
|
-
array.append('true()')
|
|
114
|
-
else:
|
|
115
|
-
array.append(sub)
|
|
116
|
-
elif sub is None:
|
|
117
|
-
array.append('true()')
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
# main function to retrieve the expression from the tree
|
|
121
|
-
# node is the node to calculate
|
|
122
|
-
# processed_nodes are the list of processed nodes
|
|
123
|
-
|
|
124
|
-
def get_node_expressions(node, processed_nodes):
|
|
125
|
-
is_calculate = issubclass(node.__class__, TriccNodeCalculateBase)
|
|
126
|
-
expression = None
|
|
127
|
-
# in case of recursive call processed_nodes will be None
|
|
128
|
-
if processed_nodes is None or is_ready_to_process(node, processed_nodes):
|
|
129
|
-
expression = get_node_expression(node, processed_nodes, is_calculate)
|
|
130
|
-
if is_calculate:
|
|
131
|
-
if expression is not None and expression != '':
|
|
132
|
-
expression = TRICC_NUMBER.format(expression)
|
|
133
|
-
else:
|
|
134
|
-
expression = ''
|
|
135
|
-
if issubclass(node.__class__, TriccNodeCalculateBase) and expression == '' and not isinstance(node, (TriccNodeWait, TriccNodeActivityEnd, TriccNodeActivityStart)):
|
|
136
|
-
logger.warning("Calculate {0} returning no calculations".format(node.get_name()))
|
|
137
|
-
expression = 'true()'
|
|
138
|
-
return expression
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def get_prev_node_expression(node, processed_nodes, is_calculate=False, excluded_name=None):
|
|
142
|
-
expression = None
|
|
143
|
-
if node is None:
|
|
144
|
-
pass
|
|
145
|
-
# when getting the prev node, we calculate the
|
|
146
|
-
if hasattr(node, 'expression_inputs') and len(node.expression_inputs) > 0:
|
|
147
|
-
expression_inputs = node.expression_inputs
|
|
148
|
-
expression_inputs = clean_list_or(expression_inputs)
|
|
149
|
-
else:
|
|
150
|
-
expression_inputs = []
|
|
151
|
-
if isinstance(node, TriccNodeBridge) and node.label=='path: signe de danger >0 ?':
|
|
152
|
-
logger.debug('hre')
|
|
153
|
-
for prev_node in node.prev_nodes:
|
|
154
|
-
if excluded_name is None or prev_node != excluded_name or (
|
|
155
|
-
isinstance(excluded_name, str) and hasattr(prev_node, 'name') and prev_node.name != excluded_name): # or isinstance(prev_node, TriccNodeActivityEnd):
|
|
156
|
-
# the rhombus should calculate only reference
|
|
157
|
-
add_sub_expression(expression_inputs, get_node_expression(prev_node, processed_nodes, is_calculate, True))
|
|
158
|
-
# avoid void is there is not conditions to avoid looping too much itme
|
|
159
|
-
expression_inputs = clean_list_or(expression_inputs)
|
|
160
|
-
|
|
161
|
-
expression = or_join(expression_inputs)
|
|
162
|
-
expression_inputs = None
|
|
163
|
-
# if isinstance(node, TriccNodeExclusive):
|
|
164
|
-
# expression = TRICC_NEGATE.format(expression)
|
|
165
|
-
# only used for activityStart
|
|
166
|
-
if isinstance(node, TriccNodeActivity) and node.base_instance is not None:
|
|
167
|
-
activity = node
|
|
168
|
-
expression_inputs = []
|
|
169
|
-
#exclude base node only if the defaulf instance number is not 0
|
|
170
|
-
if activity.base_instance.instance >1:
|
|
171
|
-
add_sub_expression(expression_inputs, get_node_expression(activity.base_instance, processed_nodes, False, True))
|
|
172
|
-
# relevance of the previous instance must be false to display this activity
|
|
173
|
-
for past_instance in activity.base_instance.instances.values():
|
|
174
|
-
if int(past_instance.root.path_len) < int(activity.root.path_len) and past_instance in processed_nodes:
|
|
175
|
-
add_sub_expression(expression_inputs, get_node_expression(past_instance, processed_nodes, False))
|
|
176
|
-
expression_activity = or_join(expression_inputs)
|
|
177
|
-
expression = nand_join(expression, expression_activity or False)
|
|
178
|
-
return expression
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
# calculate or retrieve a node expression
|
|
182
|
-
def get_node_expression(in_node, processed_nodes, is_calculate=False, is_prev=False, negate=False):
|
|
183
|
-
# in case of calculate we only use the select multiple if none is not selected
|
|
184
|
-
expression = None
|
|
185
|
-
negate_expression = None
|
|
186
|
-
node = in_node
|
|
187
|
-
|
|
188
|
-
if is_prev and isinstance(node, TriccNodeSelectOption):
|
|
189
|
-
expression = get_selected_option_expression(node)
|
|
190
|
-
#TODO remove that and manage it on the "Save" part
|
|
191
|
-
elif is_prev and isinstance(in_node, TriccNodeSelectNotAvailable):
|
|
192
|
-
expression = TRICC_SELECTED_EXPRESSION.format(get_export_name(node), 'true()')
|
|
193
|
-
elif is_prev and isinstance(node, TriccNodeRhombus):
|
|
194
|
-
if node.path is not None:
|
|
195
|
-
left = get_node_expression(node.path, processed_nodes, is_calculate, is_prev)
|
|
196
|
-
else:
|
|
197
|
-
left = 'true()'
|
|
198
|
-
r_ref=get_rhombus_terms(node, processed_nodes) # if issubclass(node.__class__, TricNodeDisplayCalulate) else TRICC_CALC_EXPRESSION.format(get_export_name(node)) #
|
|
199
|
-
expression = and_join(left, r_ref)
|
|
200
|
-
negate_expression = nand_join(left, r_ref)
|
|
201
|
-
elif isinstance(node, TriccNodeWait):
|
|
202
|
-
if is_prev:
|
|
203
|
-
# the wait don't do any calculation with the reference it is only use to wait until the reference are valid
|
|
204
|
-
return get_node_expression(node.path, processed_nodes, is_calculate, is_prev)
|
|
205
|
-
else:
|
|
206
|
-
#it is a empty calculate
|
|
207
|
-
return ''
|
|
208
|
-
elif is_prev and issubclass(node.__class__, TriccNodeDisplayCalculateBase):
|
|
209
|
-
expression = TRICC_CALC_EXPRESSION.format(get_export_name(node))
|
|
210
|
-
elif issubclass(node.__class__, TriccNodeCalculateBase):
|
|
211
|
-
if negate:
|
|
212
|
-
negate_expression = get_calculation_terms(node, processed_nodes, is_calculate, negate=True)
|
|
213
|
-
else:
|
|
214
|
-
expression = get_calculation_terms(node, processed_nodes, is_calculate)
|
|
215
|
-
elif is_prev and hasattr(node, 'required') and node.required == True:
|
|
216
|
-
expression = get_required_node_expression(node)
|
|
217
|
-
|
|
218
|
-
elif is_prev and hasattr(node, 'relevance') and node.relevance is not None and node.relevance != '':
|
|
219
|
-
expression = node.relevance
|
|
220
|
-
if expression is None:
|
|
221
|
-
expression = get_prev_node_expression(node, processed_nodes, is_calculate)
|
|
222
|
-
if isinstance(node, TriccNodeActivity) and is_prev:
|
|
223
|
-
end_nodes = node.get_end_nodes()
|
|
224
|
-
if all([end in processed_nodes for end in end_nodes]):
|
|
225
|
-
expression = and_join(expression, get_activity_end_terms(node,processed_nodes))
|
|
226
|
-
if negate:
|
|
227
|
-
if negate_expression is not None:
|
|
228
|
-
return negate_expression
|
|
229
|
-
elif expression is not None:
|
|
230
|
-
return negate_term(expression)
|
|
231
|
-
else:
|
|
232
|
-
logger.error("exclusive can not negate None from {}".format(node.get_name()))
|
|
233
|
-
# exit()
|
|
234
|
-
else:
|
|
235
|
-
return expression
|
|
236
|
-
|
|
237
|
-
def and_join(*argv):
|
|
238
|
-
if len(argv) == 0:
|
|
239
|
-
return ''
|
|
240
|
-
elif len(argv) == 2:
|
|
241
|
-
return simple_and_join(argv[0], argv[1])
|
|
242
|
-
else:
|
|
243
|
-
return '('+') and ('.join(argv)+')'
|
|
244
|
-
|
|
245
|
-
def simple_and_join(left, right):
|
|
246
|
-
expression = None
|
|
247
|
-
|
|
248
|
-
# no term is considered as True
|
|
249
|
-
left_issue = left is None or left == ''
|
|
250
|
-
right_issue = right is None or right == ''
|
|
251
|
-
left_neg = left == False or left ==0 or left =='0' or left =='false()'
|
|
252
|
-
right_neg = right == False or right ==0 or right =='0' or right =='false()'
|
|
253
|
-
if issubclass(left.__class__, TriccNodeBaseModel):
|
|
254
|
-
left = get_export_name(left)
|
|
255
|
-
if issubclass(right.__class__, TriccNodeBaseModel):
|
|
256
|
-
right = get_export_name(right)
|
|
257
|
-
|
|
258
|
-
if left_issue and right_issue:
|
|
259
|
-
logger.error("and with both terms empty")
|
|
260
|
-
elif left_neg or right_neg:
|
|
261
|
-
return 'false()'
|
|
262
|
-
elif left_issue:
|
|
263
|
-
logger.debug('and with empty left term')
|
|
264
|
-
return right
|
|
265
|
-
elif left == '1' or left == 1 or left == 'true()':
|
|
266
|
-
return right
|
|
267
|
-
elif right_issue:
|
|
268
|
-
logger.debug('and with empty right term')
|
|
269
|
-
return left
|
|
270
|
-
elif right == '1' or right == 1 or right == 'true()':
|
|
271
|
-
return left
|
|
272
|
-
else:
|
|
273
|
-
return TRICC_AND_EXPRESSION.format(left, right)
|
|
274
|
-
|
|
275
|
-
def or_join(list_or, elm_and=None):
|
|
276
|
-
cleaned_list = clean_list_or(list_or, elm_and)
|
|
277
|
-
if len(cleaned_list)>0:
|
|
278
|
-
return ' or '.join(cleaned_list)
|
|
279
|
-
|
|
280
|
-
def nand_join(left, right):
|
|
281
|
-
# no term is considered as True
|
|
282
|
-
left_issue = left is None or left == ''
|
|
283
|
-
right_issue = right is None or right == ''
|
|
284
|
-
left_neg = left == False or left ==0 or left =='0' or left =='false()'
|
|
285
|
-
right_neg = right == False or right ==0 or right =='0' or right =='false()'
|
|
286
|
-
if issubclass(left.__class__, TriccNodeBaseModel):
|
|
287
|
-
left = get_export_name(left)
|
|
288
|
-
if issubclass(right.__class__, TriccNodeBaseModel):
|
|
289
|
-
right = get_export_name(right)
|
|
290
|
-
if left_issue and right_issue:
|
|
291
|
-
logger.error("and with both terms empty")
|
|
292
|
-
elif left_issue:
|
|
293
|
-
logger.debug('and with empty left term')
|
|
294
|
-
return negate_term(right)
|
|
295
|
-
elif left == '1' or left == 1 or left == 'true()':
|
|
296
|
-
return negate_term(right)
|
|
297
|
-
elif right_issue :
|
|
298
|
-
logger.debug('and with empty right term')
|
|
299
|
-
return 'false()'
|
|
300
|
-
elif right == '1' or right == 1 or left_neg or right == 'true()':
|
|
301
|
-
return 'false()'
|
|
302
|
-
elif right_neg:
|
|
303
|
-
return left
|
|
304
|
-
else:
|
|
305
|
-
return TRICC_NAND_EXPRESSION.format(left, right)
|
|
306
|
-
|
|
307
|
-
def negate_term(expression):
|
|
308
|
-
if expression is None or expression == '':
|
|
309
|
-
return 'false()'
|
|
310
|
-
elif expression == 'false()':
|
|
311
|
-
return 'true()'
|
|
312
|
-
elif expression == 'true()':
|
|
313
|
-
return 'false()'
|
|
314
|
-
else:
|
|
315
|
-
return TRICC_NEGATE.format(expression)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
def get_activity_end_terms(node, processed_nodes):
|
|
319
|
-
end_nodes = node.get_end_nodes()
|
|
320
|
-
expression_inputs = []
|
|
321
|
-
for end_node in end_nodes:
|
|
322
|
-
add_sub_expression(expression_inputs,
|
|
323
|
-
get_node_expression(end_node, processed_nodes, is_calculate=False, is_prev=True))
|
|
324
|
-
|
|
325
|
-
return or_join(expression_inputs)
|
|
326
|
-
|
|
327
|
-
# function that generate the calculation terms return by calculate node
|
|
328
|
-
# @param node calculate node to assess
|
|
329
|
-
# @param processed_nodes list of node already processed, importnat because only processed node could be use
|
|
330
|
-
# @param is_calculate used when this funciton is called in the evaluation of another calculate
|
|
331
|
-
# @param negate use to retriece the negation of a calculation
|
|
332
|
-
def get_calculation_terms(node, processed_nodes, is_calculate=False, negate=False):
|
|
333
|
-
# returns something directly only if the negate is managed
|
|
334
|
-
expresison = None
|
|
335
|
-
if isinstance(node, TriccNodeAdd):
|
|
336
|
-
return get_add_terms(node, False, negate)
|
|
337
|
-
elif isinstance(node, TriccNodeCount):
|
|
338
|
-
return get_count_terms(node, False, negate)
|
|
339
|
-
elif isinstance(node, TriccNodeRhombus):
|
|
340
|
-
return get_rhombus_terms(node, processed_nodes, False, negate)
|
|
341
|
-
elif isinstance(node, ( TriccNodeWait)):
|
|
342
|
-
# just use to force order of question
|
|
343
|
-
expression = None
|
|
344
|
-
# in case of calulate expression evaluation, we need to get the relevance of the activity
|
|
345
|
-
# because calculate are not the the activity group
|
|
346
|
-
elif isinstance(node, (TriccNodeActivityStart)) and is_calculate:
|
|
347
|
-
expresison = get_prev_node_expression(node.activity, processed_nodes, is_calculate)
|
|
348
|
-
elif isinstance(node, (TriccNodeActivityStart, TriccNodeActivityEnd)):
|
|
349
|
-
# the group have the relevance for the activity, not needed to replicate it
|
|
350
|
-
expression = None#return get_prev_node_expression(node.activity, processed_nodes, is_calculate=False, excluded_name=None)
|
|
351
|
-
elif isinstance(node, TriccNodeExclusive):
|
|
352
|
-
if len(node.prev_nodes) == 1:
|
|
353
|
-
if isinstance(node.prev_nodes[0], TriccNodeExclusive):
|
|
354
|
-
logger.error("2 exclusives cannot be on a row")
|
|
355
|
-
exit()
|
|
356
|
-
elif issubclass(node.prev_nodes[0].__class__, TriccNodeCalculateBase):
|
|
357
|
-
return get_node_expression(node.prev_nodes[0], processed_nodes, is_prev=True, negate=True)
|
|
358
|
-
elif isinstance(node.prev_nodes[0], TriccNodeActivity):
|
|
359
|
-
return get_node_expression(node.prev_nodes[0], processed_nodes, is_calculate=False, is_prev=True,
|
|
360
|
-
negate=True)
|
|
361
|
-
else:
|
|
362
|
-
logger.error("exclusive node {} does not depend of a calculate but on {}::{}".format(node.get_name(),
|
|
363
|
-
node.prev_nodes[
|
|
364
|
-
0].__class__,
|
|
365
|
-
node.prev_nodes[
|
|
366
|
-
0].get_name()))
|
|
367
|
-
else:
|
|
368
|
-
logger.error("exclusive node {} has no ou too much parent".format(node.get_name()))
|
|
369
|
-
|
|
370
|
-
if node.reference is not None and node.expression_reference is not None :
|
|
371
|
-
expression = get_prev_node_expression(node, processed_nodes, is_calculate)
|
|
372
|
-
ref_expression = node.expression_reference.format(*[get_export_name(ref) for ref in node.reference])
|
|
373
|
-
if expression is not None and expression != '':
|
|
374
|
-
expression = and_join(expression,ref_expression)
|
|
375
|
-
else:
|
|
376
|
-
expression = ref_expression
|
|
377
|
-
else:
|
|
378
|
-
expression = get_prev_node_expression(node, processed_nodes, is_calculate)
|
|
379
|
-
|
|
380
|
-
# manage the generic negation
|
|
381
|
-
if negate:
|
|
382
|
-
|
|
383
|
-
return negate_term(expression)
|
|
384
|
-
else:
|
|
385
|
-
return expresison
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
def process_rhumbus_expression(label, operation):
|
|
389
|
-
if operation in label:
|
|
390
|
-
terms = label.split(operation)
|
|
391
|
-
if len(terms) == 2:
|
|
392
|
-
if operation == '==':
|
|
393
|
-
operation = operation[0]
|
|
394
|
-
# TODO check if number
|
|
395
|
-
return operation + terms[1].replace('?', '').strip()
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
def get_rhombus_terms(node, processed_nodes, is_calculate=False, negate=False):
|
|
399
|
-
expression = None
|
|
400
|
-
left_term = None
|
|
401
|
-
# calcualte the expression only for select muzltiple and fake calculate
|
|
402
|
-
if node.reference is not None and issubclass(node.reference.__class__, list):
|
|
403
|
-
if node.expression_reference is None and len(node.reference) == 1:
|
|
404
|
-
if node.label is not None:
|
|
405
|
-
for operation in OPERATION_LIST:
|
|
406
|
-
left_term = process_rhumbus_expression(node.label, operation)
|
|
407
|
-
if left_term is not None:
|
|
408
|
-
break
|
|
409
|
-
if left_term is None:
|
|
410
|
-
left_term = '>0'
|
|
411
|
-
ref = node.reference[0]
|
|
412
|
-
if issubclass(ref.__class__, TriccNodeBaseModel):
|
|
413
|
-
if isinstance(ref, TriccNodeActivity):
|
|
414
|
-
expression = get_activity_end_terms(ref, processed_nodes)
|
|
415
|
-
elif issubclass(ref.__class__, TriccNodeFakeCalculateBase):
|
|
416
|
-
expression = get_node_expression(ref, processed_nodes, is_calculate=True, is_prev=True)
|
|
417
|
-
else:
|
|
418
|
-
expression = TRICC_REF_EXPRESSION.format(get_export_name(ref))
|
|
419
|
-
else:
|
|
420
|
-
# expression = TRICC_REF_EXPRES
|
|
421
|
-
# SION.format(node.reference)
|
|
422
|
-
# expression = "${{{}}}".format(node.reference)
|
|
423
|
-
logger.error('reference {0} was not found in the previous nodes of node {1}'.format(node.reference,
|
|
424
|
-
node.get_name()))
|
|
425
|
-
exit()
|
|
426
|
-
elif node.expression_reference is not None and node.expression_reference != '':
|
|
427
|
-
left_term = ''
|
|
428
|
-
expression = node.expression_reference.format(*get_list_names(node.reference))
|
|
429
|
-
else:
|
|
430
|
-
logger.warning("missing epression for node {}".format(node.get_name()))
|
|
431
|
-
else:
|
|
432
|
-
logger.error('reference {0} is not a list {1}'.format(node.reference, node.get_name()))
|
|
433
|
-
exit()
|
|
434
|
-
|
|
435
|
-
if expression is not None:
|
|
436
|
-
|
|
437
|
-
if left_term is not None and re.search(" (\+)|(\-)|(or)|(and) ", expression):
|
|
438
|
-
expression = "({0}){1}".format(expression, left_term)
|
|
439
|
-
else:
|
|
440
|
-
expression = "{0}{1}".format(expression, left_term)
|
|
441
|
-
else:
|
|
442
|
-
logger.error("Rhombus reference was not found for node {}, reference {}".format(
|
|
443
|
-
node.get_name(),
|
|
444
|
-
node.reference
|
|
445
|
-
))
|
|
446
|
-
exit()
|
|
447
|
-
|
|
448
|
-
return expression
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
def clean_list_or(list_or, elm_and=None):
|
|
452
|
-
if len(list_or) == 0:
|
|
453
|
-
return []
|
|
454
|
-
if 'false()' in list_or:
|
|
455
|
-
list_or.remove('false()')
|
|
456
|
-
if '1' in list_or or 1 in list_or or 'true()' in list_or:
|
|
457
|
-
list_or = ['true()']
|
|
458
|
-
return list_or
|
|
459
|
-
if elm_and is not None:
|
|
460
|
-
if negate_term(elm_and) in list_or:
|
|
461
|
-
# we remove x and not X
|
|
462
|
-
list_or.remove(negate_term(elm_and))
|
|
463
|
-
if elm_and in list_or:
|
|
464
|
-
# we remove x and x
|
|
465
|
-
list_or.remove(elm_and)
|
|
466
|
-
for exp_prev in list_or:
|
|
467
|
-
if negate_term(exp_prev) in list_or:
|
|
468
|
-
# if there is x and not(X) in an OR list them the list is always true
|
|
469
|
-
list_or = ['true()']
|
|
470
|
-
if elm_and is not None:
|
|
471
|
-
if negate_term(elm_and) in list_or:
|
|
472
|
-
# we remove x and not X
|
|
473
|
-
list_or.remove(negate_term(elm_and))
|
|
474
|
-
else:
|
|
475
|
-
if re.search(exp_prev, ' and ') in list_or and exp_prev.replace('and ', 'and not') in list_or:
|
|
476
|
-
right = exp_prev.split(' and ')[0]
|
|
477
|
-
list_or.remove(exp_prev)
|
|
478
|
-
list_or.remove(exp_prev.replace('and ', 'and not'))
|
|
479
|
-
list_or.append(right)
|
|
480
|
-
|
|
481
|
-
if negate_term(exp_prev) == elm_and or exp_prev == elm_and:
|
|
482
|
-
list_or.remove(exp_prev)
|
|
483
|
-
|
|
484
|
-
return list_or
|
|
485
|
-
|
|
486
|
-
def get_export_name(node):
|
|
487
|
-
if node.export_name is None:
|
|
488
|
-
node.export_name = clean_name(node.name)
|
|
489
|
-
if node.name is None:
|
|
490
|
-
node.export_name= clean_name("id_" + node.id)
|
|
491
|
-
elif not ( INSTANCE_SEPARATOR in node.name or VERSION_SEPARATOR in node.name):
|
|
492
|
-
if issubclass(node.__class__, TriccNodeCalculateBase):
|
|
493
|
-
node.gen_name()
|
|
494
|
-
if node.last == False:
|
|
495
|
-
node.export_name = clean_name(node.name + VERSION_SEPARATOR + str(node.path_len))
|
|
496
|
-
else:
|
|
497
|
-
node.export_name = clean_name(node.name)
|
|
498
|
-
elif issubclass(node.__class__, (TriccNodeDisplayModel)):
|
|
499
|
-
node.gen_name()
|
|
500
|
-
if not isinstance(node, TriccNodeSelectOption) and node.activity.instance!=1:
|
|
501
|
-
node.export_name = clean_name(node.name + INSTANCE_SEPARATOR + str(node.instance))
|
|
502
|
-
#elif isinstance(node, TriccNodeActivityEnd):
|
|
503
|
-
# node.export_name = clean_name(node.name + INSTANCE_SEPARATOR + str(node.instance))
|
|
504
|
-
elif isinstance(node, TriccNodeActivityStart):
|
|
505
|
-
node.export_name = clean_name(node.name + INSTANCE_SEPARATOR + str(node.instance))
|
|
506
|
-
return (node.export_name )
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
def get_add_terms(node, processed_nodes, is_calculate=False, negate=False):
|
|
510
|
-
if negate:
|
|
511
|
-
logger.warning("negate not supported for Add node {}".format(node.get_name()))
|
|
512
|
-
terms = []
|
|
513
|
-
for prev_node in node.prev_nodes:
|
|
514
|
-
if issubclass(prev_node, TriccNodeNumber) or isinstance(node, TriccNodeCount):
|
|
515
|
-
terms.append("coalesce(${{{0}}},0)".format(get_export_name(prev_node)))
|
|
516
|
-
else:
|
|
517
|
-
terms.append(
|
|
518
|
-
"number({0})".format(get_node_expression(prev_node, processed_nodes, is_calculate=False, is_prev=True)))
|
|
519
|
-
if len(terms) > 0:
|
|
520
|
-
return ' + '.join(terms)
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
def get_count_terms(node, processed_nodes, is_calculate, negate=False):
|
|
524
|
-
terms = []
|
|
525
|
-
for prev_node in node.prev_nodes:
|
|
526
|
-
if isinstance(prev_node, TriccNodeSelectMultiple):
|
|
527
|
-
if negate:
|
|
528
|
-
terms.append(TRICC_SELECT_MULTIPLE_CALC_NONE_EXPRESSION.format(get_export_name(prev_node)))
|
|
529
|
-
else:
|
|
530
|
-
terms.append(TRICC_SELECT_MULTIPLE_CALC_EXPRESSION.format(get_export_name(prev_node)))
|
|
531
|
-
elif isinstance(prev_node, (TriccNodeSelectYesNo, TriccNodeSelectNotAvailable)):
|
|
532
|
-
terms.append(TRICC_SELECTED_EXPRESSION.format(get_export_name(prev_node), '1'))
|
|
533
|
-
elif isinstance(prev_node, TriccNodeSelectOption):
|
|
534
|
-
terms.append(get_selected_option_expression(prev_node))
|
|
535
|
-
else:
|
|
536
|
-
if negate:
|
|
537
|
-
terms.append("number(number({0})=0)".format(
|
|
538
|
-
get_node_expression(prev_node, processed_nodes, is_calculate=False, is_prev=True)))
|
|
539
|
-
else:
|
|
540
|
-
terms.append("number({0})".format(
|
|
541
|
-
get_node_expression(prev_node, processed_nodes, is_calculate=False, is_prev=True)))
|
|
542
|
-
if len(terms) > 0:
|
|
543
|
-
return ' + '.join(terms)
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
def get_list_names(list):
|
|
547
|
-
names = []
|
|
548
|
-
for elm in list:
|
|
549
|
-
if issubclass(elm.__class__, TriccNodeBaseModel):
|
|
550
|
-
names.append(get_export_name(elm))
|
|
551
|
-
elif isinstance(elm, str):
|
|
552
|
-
names.append(elm)
|
|
553
|
-
return names
|
tricc/converters/utils.py
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import random
|
|
3
|
-
import string
|
|
4
|
-
|
|
5
|
-
import html2text
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
OPERATION_LIST = [ '>=', '<=', '==','=','>','<']
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
logger = logging.getLogger("default")
|
|
12
|
-
|
|
13
|
-
def replace_all(text, list_char, replacement):
|
|
14
|
-
for i in list_char:
|
|
15
|
-
text = text.replace(i, replacement)
|
|
16
|
-
return text
|
|
17
|
-
|
|
18
|
-
def clean_str(name):
|
|
19
|
-
return replace_all(name, ['-', ' ', '.', ','],'_')
|
|
20
|
-
|
|
21
|
-
def clean_name( name, prefix='' ):
|
|
22
|
-
name = clean_str(name)
|
|
23
|
-
if name[0].isdigit():
|
|
24
|
-
name = 'id_' + name
|
|
25
|
-
elif name[0].isdigit() == '_':
|
|
26
|
-
name = name[1:]
|
|
27
|
-
return name
|
|
28
|
-
|
|
29
|
-
def generate_id():
|
|
30
|
-
return ''.join(random.choices(string.ascii_lowercase, k=8))
|
|
31
|
-
|
|
32
|
-
# the soup.text strips off the html formatting also
|
|
33
|
-
def remove_html(string):
|
|
34
|
-
text = html2text.html2text(string) # retrive pure text from html
|
|
35
|
-
text = text.strip('\n') # get rid of empty lines at the end (and beginning)
|
|
36
|
-
text = text.split('\n') # split string into a list at new lines
|
|
37
|
-
text = '\n'.join([i.strip(' ') for i in text if i]) # in each element in that list strip empty space (at the end of line)
|
|
38
|
-
# and delete empty lines
|
|
39
|
-
return text
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|