tricc-oo 1.4.16__py3-none-any.whl → 1.4.22__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 CHANGED
@@ -145,7 +145,7 @@ if __name__ == "__main__":
145
145
  if in_filepath is None:
146
146
  print_help()
147
147
  sys.exit(2)
148
- in_filepath_list = in_filepath.split(',')
148
+
149
149
  if not download_dir:
150
150
  download_dir = out_path
151
151
  debug_path = os.fspath(out_path + "/debug.log")
@@ -165,6 +165,7 @@ if __name__ == "__main__":
165
165
  setup_logger("default", debug_file_path, logging.INFO)
166
166
  file_content = []
167
167
  files = []
168
+ in_filepath_list = in_filepath.split(',')
168
169
  for in_filepath in in_filepath_list:
169
170
  pre, ext = os.path.splitext(in_filepath)
170
171
 
@@ -33,6 +33,7 @@ FUNCTION_MAP = {
33
33
  class cqlToXlsFormVisitor(cqlVisitor):
34
34
  def __init__(self):
35
35
  self.xlsform_rows = []
36
+ self.errors= []
36
37
 
37
38
  def resolve_scv(self, arg):
38
39
 
@@ -42,9 +43,15 @@ class cqlToXlsFormVisitor(cqlVisitor):
42
43
  # if no code or not found return None
43
44
  if arg.startswith('"') and arg.endswith('"'):
44
45
  return TriccReference(arg[1:-1])
45
- else:
46
+ elif arg.lower() in ['true', 'false']:
47
+ return TriccStatic(arg.lower() == 'true')
48
+ elif arg != 'runner':
49
+ self.errors.append(f"'{arg}' will be poccessed as reference ")
46
50
  return TriccReference(arg)
47
51
 
52
+ else:
53
+ return 'runner'
54
+
48
55
  def translate(self, arg, type=ANY):
49
56
  return self.resolve_scv(arg) or str(arg)
50
57
 
@@ -150,6 +157,13 @@ class cqlToXlsFormVisitor(cqlVisitor):
150
157
  function_name = ctx.getChild(2).getText()
151
158
  return not_clean(self._get_membership_expression(ctx, function_name))
152
159
 
160
+ def visitInvocationExpressionTerm(self, ctx):
161
+ result = super().visitInvocationExpressionTerm(ctx)
162
+ if isinstance(result, list) and all(isinstance(x, TriccStatic) for x in result):
163
+ value = '.'.join([x.value for x in result])
164
+ logger.warning(f"guessed reference for '{value}'")
165
+ return TriccReference(value)
166
+ return result
153
167
 
154
168
  def visitBetweenExpression(self, ctx):
155
169
  ref = self.visit(ctx.expression(0))
@@ -361,13 +375,13 @@ class CQLErrorListener(ErrorListener):
361
375
  self.errors.append(error)
362
376
 
363
377
  def transform_cql_to_operation(cql_input, context=None):
364
- cql_input = f"""
378
+ lib_input = f"""
365
379
  library runner
366
380
 
367
381
  define "calc":
368
382
  {cql_input.replace('−', '-')}
369
383
  """
370
- input_stream = InputStream(chr(10).join(cql_input.split('\n')))
384
+ input_stream = InputStream(chr(10).join(lib_input.split('\n')))
371
385
  lexer = cqlLexer(input_stream)
372
386
  stream = CommonTokenStream(lexer)
373
387
  parser = cqlParser(stream)
@@ -383,12 +397,18 @@ def transform_cql_to_operation(cql_input, context=None):
383
397
  # Check for errors
384
398
  if error_listener.errors:
385
399
  for error in error_listener.errors:
386
- print(f"CQL Grammar Error: {error}")
400
+ print(f"CQL Grammar Error: {error} \n in:\n {cql_input}")
387
401
  return None # Or handle errors as appropriate for your use case
388
402
 
389
403
  # If no errors, proceed with visitor
390
404
  visitor = cqlToXlsFormVisitor()
405
+
391
406
  visitor.visit(tree)
407
+ if visitor.errors:
408
+ logger.warning(f"while visiting cql: \n{cql_input}")
409
+ for e in visitor.errors:
410
+ logger.warning(e)
411
+
392
412
  return visitor.xlsform_rows[0]['calculation']
393
413
 
394
414
  def transform_cql_lib_to_operations(cql_input):
@@ -16,6 +16,10 @@ logger = logging.getLogger("default")
16
16
 
17
17
 
18
18
  def lookup_codesystems_code(codesystems, ref):
19
+ if ref.startswith('final.'):
20
+ concept = lookup_codesystems_code(codesystems, ref[6:])
21
+ if concept:
22
+ return concept
19
23
  for code_system in codesystems.values():
20
24
  for concept in code_system.concept or []:
21
25
  if concept.code == ref:
@@ -94,13 +94,13 @@ TYPE_MAP = {
94
94
 
95
95
  TriccNodeType.text: {
96
96
  "objects": ["UserObject", "object"],
97
- "attributes": ["relevance"],
97
+ "attributes": ["save", "relevance"],
98
98
  "mandatory_attributes": ["label", 'name'],
99
99
  "model": TriccNodeText
100
100
  },
101
101
  TriccNodeType.date: {
102
102
  "objects": ["UserObject", "object"],
103
- "attributes": ["relevance"],
103
+ "attributes": ["save", "relevance"],
104
104
  "mandatory_attributes": ["label", "name"],
105
105
  "model": TriccNodeDate
106
106
  },
@@ -35,12 +35,12 @@ def get_export_name(node, replace_dots=True):
35
35
  node.gen_name()
36
36
  if isinstance(node, TriccNodeSelectOption):
37
37
  node.export_name = node.name
38
- elif isinstance(node, TriccNodeActivityStart):
39
- node.export_name = clean_name(node.name + INSTANCE_SEPARATOR + str(node.instance), replace_dots=replace_dots)
40
- elif isinstance(node, TriccNodeInput):
41
- node.export_name = clean_name('load.' +node.name, replace_dots=replace_dots)
42
38
  elif node.last == False:
43
39
  node.export_name = clean_name(node.name + VERSION_SEPARATOR + str(node.version), replace_dots=replace_dots)
40
+ elif node.activity.instance>1:
41
+ node.export_name = clean_name(node.name + INSTANCE_SEPARATOR + str(node.activity.instance), replace_dots=replace_dots)
42
+ elif isinstance(node, TriccNodeInput):
43
+ node.export_name = clean_name('load.' +node.name, replace_dots=replace_dots)
44
44
  else:
45
45
  node.export_name = clean_name(node.name, replace_dots=replace_dots)
46
46
 
@@ -35,6 +35,7 @@ DISPLAY_ATTRIBUTES = [
35
35
  'help'
36
36
  ]
37
37
  logger = logging.getLogger("default")
38
+ import html2text
38
39
 
39
40
 
40
41
 
@@ -211,6 +212,7 @@ def process_edges(diagram, media_path, activity, nodes):
211
212
  ):
212
213
  if isinstance(nodes[edge.source], TriccNodeRhombus):
213
214
  edge.source = nodes[edge.source].path.id
215
+ edge.source_external_id = None
214
216
  processed = True
215
217
  elif label.lower() in (TRICC_YES_LABEL) or label == "":
216
218
  # do nothinbg for yes
@@ -219,7 +221,7 @@ def process_edges(diagram, media_path, activity, nodes):
219
221
  calc = process_factor_edge(edge, nodes)
220
222
  elif label.lower() in TRICC_NO_LABEL:
221
223
  calc = process_exclusive_edge(edge, nodes)
222
- elif any(reserved in label.lower() for reserved in ([str(o) for o in list(TriccOperator)] + list(OPERATION_LIST.keys()) + ['$this'])):
224
+ elif any(reserved in html2text.html2text(label.lower()) for reserved in ([str(o) for o in list(TriccOperator)] + list(OPERATION_LIST.keys()) + ['$this'])):
223
225
  # manage comment
224
226
  calc = process_condition_edge(edge, nodes)
225
227
  else:
@@ -240,6 +242,10 @@ def process_edges(diagram, media_path, activity, nodes):
240
242
  "not management found",
241
243
  )
242
244
  )
245
+ elif edge.source in nodes and isinstance(nodes[edge.source], TriccNodeRhombus):
246
+ logger.critical(
247
+ "rhombus {} node with labelless edges".format(nodes[edge.source].get_name())
248
+ )
243
249
  if not end_found:
244
250
  fake_end = TriccNodeActivityEnd(id=generate_id(f"e{activity.name}"), activity=activity, group=activity)
245
251
  last_nodes = [
@@ -974,7 +980,7 @@ def process_exclusive_edge(edge, nodes):
974
980
 
975
981
 
976
982
  def process_yesno_edge(edge, nodes):
977
- if edge.value is None:
983
+ if not edge.value:
978
984
  logger.critical(
979
985
  "yesNo {} node with labelless edges".format(nodes[edge.source].get_name())
980
986
  )
tricc_oo/models/base.py CHANGED
@@ -112,16 +112,19 @@ class TriccBaseModel(BaseModel):
112
112
  version: int = 1
113
113
  def get_datatype(self):
114
114
  return self.datatype or self.tricc_type
115
-
115
+
116
+ def get_next_instance(self):
117
+ if getattr(self, 'instances', None):
118
+ return max(100, *[n.instance for n in self.instances.values()]) + 1
119
+ if getattr(self, 'base_instance', None) and getattr(self.base_instance, 'instances', None):
120
+ return max(100, *[n.instance for n in self.base_instance.instances.values()]) + 1
121
+ return max(100,self.instance) + 1
122
+
116
123
  def to_dict(self):
117
124
  return {key: value for key, value in vars(self).items() if not key.startswith('_')}
118
125
 
119
126
  def make_instance(self, nb_instance, **kwargs):
120
127
  instance = self.copy()
121
- # change the id to avoid collision of name
122
- instance.id = generate_id(f"{self.id}{nb_instance}")
123
- instance.instance = int(nb_instance)
124
- instance.base_instance = self
125
128
  attr_dict = self.to_dict()
126
129
  for attr, value in attr_dict.items():
127
130
  if not attr.startswith('_') and value is not None:
@@ -132,6 +135,13 @@ class TriccBaseModel(BaseModel):
132
135
  setattr(instance, attr, value)
133
136
  except Exception as e:
134
137
  logger.warning(f"Warning: Could not copy attribute {attr}: {e}")
138
+
139
+ # change the id to avoid collision of name
140
+ instance.id = generate_id(f"{self.id}{nb_instance}")
141
+ instance.instance = int(nb_instance)
142
+ instance.base_instance = self
143
+
144
+
135
145
  # assign the defualt group
136
146
  # if activity is not None and self.group == activity.base_instance:
137
147
  # instance.group = instance
@@ -230,20 +240,20 @@ class TriccNodeBaseModel(TriccBaseModel):
230
240
  # to be updated while processing because final expression will be possible to build$
231
241
  # #only the last time the script will go through the node (all prev node expression would be created
232
242
  def get_name(self):
233
- result = str(super().get_name())
243
+ result = self.__class__.__name__[9:]# str(super().get_name())
234
244
  name = getattr(self, 'name', None)
235
245
  label = getattr(self, 'label', None)
236
246
 
237
247
  if name:
238
- result = result + "::" + name
248
+ result += name
239
249
  if label:
240
- result = result + "::" + (
250
+ result += "::" + (
241
251
  next(iter(self.label.values())) if isinstance(self.label, Dict) else self.label
242
252
  )
243
- if len(result) < 50:
253
+ if len(result) < 80:
244
254
  return result
245
255
  else:
246
- return result[:50]
256
+ return result[:80]
247
257
 
248
258
 
249
259
 
@@ -269,7 +279,7 @@ class TriccNodeBaseModel(TriccBaseModel):
269
279
  if self.name is None:
270
280
  self.name = get_rand_name(self.id)
271
281
  def get_references(self):
272
- return OrderedSet([self])
282
+ return OrderedSet()
273
283
 
274
284
  class TriccStatic(BaseModel):
275
285
  value: Union[str, float, int, bool]
@@ -302,7 +312,7 @@ class TriccStatic(BaseModel):
302
312
  return str(self.value)
303
313
 
304
314
  def __repr__(self):
305
- return "TriccStatic:"+str(type(self.value))+':' +str(self.value)
315
+ return self.__class__.__name__+":"+str(type(self.value))+':' +str(self.value)
306
316
 
307
317
  def get_references(self):
308
318
  return OrderedSet()
@@ -706,17 +716,13 @@ def nand_join(left, right):
706
716
  right_issue = right is None or right == ''
707
717
  left_neg = left == False or left == 0 or left == '0' or left == TriccStatic(False)
708
718
  right_neg = right == False or right == 0 or right == '0' or right == TriccStatic(False)
709
- if issubclass(left.__class__, TriccNodeBaseModel):
710
- left = get_export_name(left)
711
- if issubclass(right.__class__, TriccNodeBaseModel):
712
- right = get_export_name(right)
713
719
  if left_issue and right_issue:
714
720
  logger.critical("and with both terms empty")
715
721
  elif left_issue:
716
722
  logger.debug('and with empty left term')
717
- return negate_term(right)
723
+ return not_clean(right)
718
724
  elif left == '1' or left == 1 or left == TriccStatic(True):
719
- return negate_term(right)
725
+ return not_clean(right)
720
726
  elif right_issue :
721
727
  logger.debug('and with empty right term')
722
728
  return TriccStatic(False)
@@ -725,7 +731,7 @@ def nand_join(left, right):
725
731
  elif right_neg:
726
732
  return left
727
733
  else:
728
- return and_join([left, negate_term(right)])
734
+ return and_join([left, not_clean(right)])
729
735
 
730
736
 
731
737
  TriccGroup.update_forward_refs()
tricc_oo/models/tricc.py CHANGED
@@ -96,7 +96,9 @@ class TriccNodeActivity(TriccNodeBaseModel):
96
96
  return self.instances[instance_nb]
97
97
  else:
98
98
  instance = super().make_instance(instance_nb, activity=None)
99
- self.instances[instance_nb] = instance
99
+ base_instance = (self.base_instance or self)
100
+ base_instance.instances[instance_nb] = instance
101
+ instance.base_instance = base_instance
100
102
  # instance.base_instance = self
101
103
  # we duplicate all the related nodes (not the calculate, duplication is manage in calculate version code)
102
104
  nodes = {}
@@ -124,7 +126,7 @@ class TriccNodeActivity(TriccNodeBaseModel):
124
126
  if node in self.calculates and instance_node:
125
127
  instance.calculates.append(instance_node)
126
128
  # update parents
127
- for node in list(filter(lambda p_node: hasattr(p_node, 'parent'),list(instance.nodes.values()))):
129
+ for node in list(filter(lambda p_node: getattr(p_node, 'parent', None) is not None, list(instance.nodes.values()))):
128
130
  new_parent = list(filter(lambda p_node: p_node.base_instance == node.parent,list(instance.nodes.values())))
129
131
  if new_parent:
130
132
  node.parent = new_parent[0]
@@ -179,6 +181,7 @@ class TriccNodeActivity(TriccNodeBaseModel):
179
181
  if issubclass(node_instance.__class__, TriccRhombusMixIn):
180
182
  old_path = node_origin.path
181
183
  if old_path is not None:
184
+ node_instance.path = None
182
185
  for n in node_instance.activity.nodes.values():
183
186
  if n.base_instance.id == old_path.id:
184
187
  node_instance.path = n
@@ -18,6 +18,9 @@ from tricc_oo.visitors.tricc import (
18
18
  add_calculate,
19
19
  TRICC_TRUE_VALUE,
20
20
  TRICC_FALSE_VALUE,
21
+ get_applicability_expression,
22
+ get_prev_instance_skip_expression,
23
+ get_process_skip_expression,
21
24
  )
22
25
 
23
26
  logger = logging.getLogger("default")
@@ -32,7 +35,7 @@ BOOLEAN_MAP = {
32
35
 
33
36
 
34
37
  def start_group(
35
- strategy, cur_group, groups, df_survey, df_calculate, relevance=False, **kwargs
38
+ strategy, cur_group, groups, df_survey, df_calculate, processed_nodes, process, relevance=False, **kwargs
36
39
  ):
37
40
  name = get_export_name(cur_group)
38
41
 
@@ -46,20 +49,24 @@ def start_group(
46
49
  relevance = (
47
50
  relevance and cur_group.relevance is not None and cur_group.relevance != ""
48
51
  )
52
+
49
53
 
50
54
  group_calc_required = (
51
55
  False and relevance and not is_activity and len(relevance) > 100
52
56
  )
53
57
 
54
58
  relevance_expression = cur_group.relevance
59
+ relevance_expression = get_applicability_expression(cur_group, processed_nodes, process, relevance_expression)
60
+ relevance_expression = get_prev_instance_skip_expression(cur_group, processed_nodes, process, relevance_expression)
61
+ relevance_expression = get_process_skip_expression(cur_group, processed_nodes, process, relevance_expression)
62
+
55
63
  if not relevance:
56
64
  relevance_expression = ""
57
- elif isinstance(relevance_expression, TriccOperation):
65
+ elif isinstance(relevance_expression, (TriccOperation, TriccStatic)):
58
66
  relevance_expression = strategy.get_tricc_operation_expression(
59
67
  relevance_expression
60
68
  )
61
- elif isinstance(relevance_expression, TriccStatic):
62
- relevance_expression = str(relevance_expression.value)
69
+
63
70
 
64
71
  # elif is_activity:
65
72
  # relevance_expression = TRICC_CALC_EXPRESSION.format(get_export_name(cur_group.root))
@@ -628,118 +635,3 @@ def get_input_calc_line(node, replace_dots=True):
628
635
  ]
629
636
 
630
637
 
631
- def get_diagnostic_start_group_line():
632
- label = langs.get_trads("List of diagnostics", force_dict=True)
633
- empty = langs.get_trads("", force_dict=True)
634
- return [
635
- "begin group",
636
- "l_diag_list25",
637
- *list(label.values()),
638
- *list(empty.values()), # hint
639
- *list(empty.values()), # help
640
- "", # default
641
- "field-list", #'appearance',
642
- "", #'constraint',
643
- *list(empty.values()), #'constraint_message'
644
- "", #'relevance'
645
- "", #'disabled'
646
- "", #'required'
647
- *list(empty.values()), #'required message'
648
- "", #'read only'
649
- "", #'expression'
650
- "", #'repeat_count'
651
- "", #'image'
652
- "",
653
- ]
654
-
655
-
656
- def get_diagnostic_add_line(diags, df_choice):
657
- for diag in diags:
658
- df_choice.loc[len(df_choice)] = [
659
- "tricc_diag_add",
660
- get_export_name(diag),
661
- *list(langs.get_trads(diag.label, True).values()),
662
- "", # filter
663
- "", # min y
664
- "", # max Y
665
- "", # l
666
- "", # m
667
- "", # s
668
- ]
669
- label = langs.get_trads("Add a missing diagnostic", force_dict=True)
670
- empty = langs.get_trads("", force_dict=True)
671
- return [
672
- "select_multiple tricc_diag_add",
673
- "new_diag",
674
- *list(label.values()),
675
- *list(empty.values()), # hint
676
- *list(empty.values()), # help
677
- "", # default
678
- "minimal", #'appearance',
679
- "", #'constraint',
680
- *list(empty.values()), #'constraint_message',
681
- "", #'relevance'
682
- "", #'disabled'
683
- "", #'required'
684
- *list(empty.values()), #'required message'
685
- "", #'read only'
686
- "", #'expression'
687
- "", #'repeat_count'
688
- "", #'image'
689
- "",
690
- ]
691
-
692
-
693
- def get_diagnostic_none_line(diags):
694
- relevance = ""
695
- for diag in diags:
696
- relevance += TRICC_CALC_EXPRESSION.format(get_export_name(diag)) + " or "
697
- label = langs.get_trads(
698
- "Aucun diagnostic trouvé par l'outil mais cela ne veut pas dire que le patient est en bonne santé",
699
- force_dict=True,
700
- )
701
- empty = langs.get_trads("", force_dict=True)
702
- return [
703
- "note",
704
- "l_diag_none25",
705
- *list(label.values()),
706
- *list(empty.values()),
707
- *list(empty.values()),
708
- "", # default
709
- "", #'appearance',
710
- "", #'constraint',
711
- *list(empty.values()),
712
- f"not({relevance[:-4]})", #'relevance'
713
- "", #'disabled'
714
- "", #'required'
715
- *list(empty.values()),
716
- "", #'read only'
717
- "", #'expression'
718
- "", #'repeat_count'
719
- "", #'image' TRICC_NEGATE
720
- "",
721
- ]
722
-
723
-
724
- def get_diagnostic_stop_group_line():
725
- label = langs.get_trads("", force_dict=True)
726
- return [
727
- "end group",
728
- "l_diag_list25",
729
- *list(label.values()),
730
- *list(label.values()),
731
- *list(label.values()), # help
732
- "", # default
733
- "", #'appearance',
734
- "", #'constraint',
735
- *list(label.values()),
736
- "", #'relevance'
737
- "", #'disabled'
738
- "", #'required'
739
- *list(label.values()),
740
- "", #'read only'
741
- "", #'expression'
742
- "", #'repeat_count'
743
- "", #'image'
744
- "",
745
- ]
@@ -73,29 +73,30 @@ class BaseInputStrategy:
73
73
  # setting the activity/group to main
74
74
  prev_bridge = root
75
75
  prev_process = None
76
- for process in sorted_pages:
77
- nodes = {page.id: page for page in sorted_pages[process]}
78
- if prev_process:
79
- prev_bridge = get_activity_wait(
80
- prev_bridge,
81
- sorted_pages[prev_process],
82
- nodes.values(),
83
- activity=app,
84
- )
85
- else:
86
- for a in nodes:
87
- set_prev_next_node(
76
+ for process in self.processes:
77
+ if process in sorted_pages:
78
+ nodes = {page.id: page for page in sorted_pages[process]}
79
+ if prev_process:
80
+ prev_bridge = get_activity_wait(
88
81
  prev_bridge,
89
- a,
90
- edge_only=True
82
+ sorted_pages[prev_process],
83
+ nodes.values(),
84
+ activity=app,
91
85
  )
92
- app.nodes[prev_bridge.id] = prev_bridge
93
-
94
- for n in nodes.values():
95
- n.activity = app
96
- n.group = app
97
- app.nodes[n.id] = n
98
- prev_process = process
86
+ else:
87
+ for a in nodes:
88
+ set_prev_next_node(
89
+ prev_bridge,
90
+ a,
91
+ edge_only=True
92
+ )
93
+ app.nodes[prev_bridge.id] = prev_bridge
94
+
95
+ for n in nodes.values():
96
+ n.activity = app
97
+ n.group = app
98
+ app.nodes[n.id] = n
99
+ prev_process = process
99
100
 
100
101
 
101
102
  return app
@@ -126,8 +126,8 @@ class DrawioStrategy(BaseInputStrategy):
126
126
 
127
127
  node_edge = list(
128
128
  filter(lambda x: (
129
- (x.source_external_id and x.source_external_id == node.external_id) or
130
129
  ( x.source and x.source == node.id) or
130
+ (not x.source and x.source_external_id and x.source_external_id == node.external_id) or
131
131
  x.source == node
132
132
  ), page.edges)
133
133
  )
@@ -85,7 +85,7 @@ class XLSFormStrategy(BaseOutPutStrategy):
85
85
 
86
86
 
87
87
  def clean_coalesce(self, expression):
88
- if re.match(r"^coalesce\(\${[^}]+},''\)$", expression):
88
+ if re.match(r"^coalesce\(\${[^}]+},''\)$", str(expression)):
89
89
  return expression[9:-4]
90
90
  return expression
91
91
 
@@ -174,8 +174,9 @@ class XLSFormStrategy(BaseOutPutStrategy):
174
174
  cur_group = activity
175
175
  groups[activity.id] = 0
176
176
  path_len = 0
177
+ process = ['main']
177
178
  # keep the vesrions on the group id, max version
178
- start_group(self, cur_group=cur_group, groups=groups, **self.get_kwargs())
179
+ start_group(self, cur_group=cur_group, groups=groups, processed_nodes=processed_nodes, process=process, **self.get_kwargs())
179
180
  walktrhough_tricc_node_processed_stached(
180
181
  activity.root,
181
182
  self.generate_export,
@@ -183,6 +184,7 @@ class XLSFormStrategy(BaseOutPutStrategy):
183
184
  stashed_nodes,
184
185
  path_len,
185
186
  cur_group=activity.root.group,
187
+ process=process,
186
188
  recursive=False,
187
189
  **self.get_kwargs()
188
190
  )
@@ -218,6 +220,8 @@ class XLSFormStrategy(BaseOutPutStrategy):
218
220
  self,
219
221
  cur_group=s_node.group,
220
222
  groups=groups,
223
+ processed_nodes=processed_nodes,
224
+ process=process,
221
225
  relevance=True,
222
226
  **self.get_kwargs()
223
227
  )
@@ -314,9 +318,8 @@ class XLSFormStrategy(BaseOutPutStrategy):
314
318
  save_calc = save_calc.iloc[0]
315
319
  if save_calc["name"] != drop_calc["name"]:
316
320
  self.df_survey.replace(
317
- "\$\{" + drop_calc["name"] + "\}",
318
- "\$\{" + save_calc["name"] + "\}",
319
- regex=True,
321
+ "${" + drop_calc["name"] + "}",
322
+ "${" + save_calc["name"] + "}",
320
323
  )
321
324
  else:
322
325
  logger.critical(
@@ -325,7 +328,7 @@ class XLSFormStrategy(BaseOutPutStrategy):
325
328
  )
326
329
  )
327
330
  for index, empty_calc in df_empty_calc.iterrows():
328
- self.df_survey.replace("\$\{" + empty_calc["name"] + "\}", "1", regex=True)
331
+ self.df_survey.replace("${" + empty_calc["name"] + "}", "1", regex=True)
329
332
 
330
333
  # TODO try to reinject calc to reduce complexity
331
334
  for i, c in self.df_calculate[
@@ -334,7 +337,7 @@ class XLSFormStrategy(BaseOutPutStrategy):
334
337
  real_calc = re.find(r"^number\((.+)\)$", c["calculation"])
335
338
  if real_calc is not None and real_calc != "":
336
339
  self.df_survey[~self.df_survey["name"] == c["name"]].replace(
337
- real_calc, "\$\{" + c["name"] + "\}"
340
+ real_calc, "${" + c["name"] + "}"
338
341
  )
339
342
 
340
343
  df_duplicate = self.df_survey[
@@ -1,10 +1,6 @@
1
1
  import logging
2
2
  from tricc_oo.models.tricc import TriccNodeActivity
3
3
  from tricc_oo.models.calculate import TriccNodeProposedDiagnosis, TriccNodeInput
4
- from tricc_oo.serializers.xls_form import (
5
- get_diagnostic_none_line,
6
- get_diagnostic_start_group_line,
7
- get_diagnostic_stop_group_line)
8
4
  from tricc_oo.converters.tricc_to_xls_form import get_export_name
9
5
  from tricc_oo.strategies.output.xls_form import XLSFormStrategy
10
6
  from tricc_oo.models.lang import SingletonLangClass