tricc-oo 1.6.14__py3-none-any.whl → 1.6.16__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.
@@ -483,7 +483,7 @@ def set_additional_attributes(attribute_names, elm, node):
483
483
  # input expression can add a condition to either relevance (display) or calculate expression
484
484
  if attributename == "expression_inputs":
485
485
  attribute = [attribute]
486
- elif attributename == "instance":
486
+ elif attributename in ["priority", "instance"]:
487
487
  attribute = int(attribute)
488
488
  else:
489
489
  attribute
@@ -612,7 +612,11 @@ def inject_bridge_path(node, nodes):
612
612
  calc = TriccNodeDisplayBridge(**data)
613
613
  else:
614
614
  calc = TriccNodeBridge(**data)
615
-
615
+ if node:
616
+ priority = getattr(node, 'priority', None)
617
+ if priority:
618
+ calc.priority = priority
619
+
616
620
  for e in node.activity.edges:
617
621
  if e.target == node.id:
618
622
  if e.source in node.activity.nodes and len(node.activity.nodes[e.source].next_nodes):
@@ -632,23 +636,23 @@ def enrich_node(diagram, media_path, edge, node, activity, help_before=False):
632
636
  # get node and process type
633
637
  type, message = get_message(diagram, edge.source_external_id)
634
638
  if type is not None:
635
- if type == "help":
636
- help = TriccNodeMoreInfo(
637
- id=generate_id(),
638
- name=f"{node.name}.more_info",
639
- label=message,
640
- parent=node,
641
- group=node.group,
642
- activity=node.activity,
643
- required=None,
644
- )
645
- # node.help = message
646
- if help_before:
647
- inject_node_before(help, node, activity)
648
- else:
649
- set_prev_next_node(node, help, edge_only=True, activity=activity)
650
- activity.nodes[help.id] = help
651
- return help, None
639
+ # if type == "help":
640
+ # help = TriccNodeMoreInfo(
641
+ # id=generate_id(),
642
+ # name=f"{node.name}.more_info",
643
+ # label=message,
644
+ # parent=node,
645
+ # group=node.group,
646
+ # activity=node.activity,
647
+ # required=None,
648
+ # )
649
+ # # node.help = message
650
+ # if help_before:
651
+ # inject_node_before(help, node, activity)
652
+ # else:
653
+ # set_prev_next_node(node, help, edge_only=True, activity=activity)
654
+ # activity.nodes[help.id] = help
655
+ # return help, None
652
656
 
653
657
  if type in (TriccNodeType.start, TriccNodeType.activity_start):
654
658
  return True
@@ -432,7 +432,7 @@ def get_attr_if_exists(strategy, node, column, map_array):
432
432
  return ""
433
433
 
434
434
 
435
- def get_more_info_select(strategy, node):
435
+ def get_more_info_select(strategy, base_name, relevance):
436
436
  values = []
437
437
  for column in SURVEY_MAP:
438
438
  if column == "type":
@@ -440,28 +440,30 @@ def get_more_info_select(strategy, node):
440
440
  elif column == "label":
441
441
  values.append(strategy.get_empty_label())
442
442
  elif column == "name":
443
- values.append(get_export_name(node) + "_optin")
444
- elif column == "hint":
445
- print(get_xfrom_trad(strategy, node, column, SURVEY_MAP, clean_html=True))
446
- values.append(get_xfrom_trad(strategy, node, column, SURVEY_MAP, clean_html=True))
443
+ values.append(base_name + "_optin")
447
444
  elif column == "relevance":
448
- values.append(get_xfrom_trad(strategy, node.parent, column, SURVEY_MAP))
445
+ values.append(relevance)
449
446
  else:
450
447
  values.append(get_xfrom_trad(strategy, None, column, SURVEY_MAP))
451
448
  return values
452
449
 
453
450
 
454
- def get_more_info_message(strategy, node):
451
+ def get_more_info_message(strategy, base_name, message):
455
452
  values = []
456
453
  for column in SURVEY_MAP:
457
454
  if column == "type":
458
455
  values.append("note")
456
+ elif column == "name":
457
+ values.append(base_name)
459
458
  elif column == "relevance":
460
- values.append(f"${{{get_export_name(node)}_optin}} = 1")
461
- elif column.startswith("hint"):
462
- values.append(langs.get_trads("", trad=None))
459
+ values.append(f"${{{base_name}_optin}} = 1")
460
+ elif column.startswith("label"):
461
+ arr = column.split("::")
462
+ column = arr[0]
463
+ trad = arr[1] if len(arr) == 2 else None
464
+ values.append(langs.get_trads(message, trad=trad))
463
465
  else:
464
- values.append(get_xfrom_trad(strategy, node, column, SURVEY_MAP, clean_html=True))
466
+ values.append(get_xfrom_trad(strategy, None, column, SURVEY_MAP, clean_html=True))
465
467
  return values
466
468
 
467
469
 
@@ -482,6 +484,13 @@ def get_more_info_choice(strategy):
482
484
  return values
483
485
 
484
486
 
487
+ def inject_more_info(strategy, base_name, relevance, message, df_survey, df_choice):
488
+ df_survey.loc[len(df_survey)] = get_more_info_select(strategy, base_name, relevance)
489
+ df_survey.loc[len(df_survey)] = get_more_info_message(strategy, base_name, message)
490
+ if len(df_choice[(df_choice["list_name"] == "more_info")]) == 0:
491
+ df_choice.loc[len(df_choice)] = get_more_info_choice(strategy)
492
+
493
+
485
494
  def generate_xls_form_export(
486
495
  strategy,
487
496
  node,
@@ -492,6 +501,7 @@ def generate_xls_form_export(
492
501
  df_calculate,
493
502
  cur_group,
494
503
  calculates,
504
+ help_before=False,
495
505
  **kwargs,
496
506
  ):
497
507
  # check that all prev nodes were processed
@@ -503,6 +513,15 @@ def generate_xls_form_export(
503
513
  codesystems=kwargs.get("codesystems", None),
504
514
  ):
505
515
  if node not in processed_nodes:
516
+ if help_before and getattr(node, 'help', None):
517
+ base_name=f"{get_export_name(node)}_more_info"
518
+ inject_more_info(
519
+ strategy,
520
+ base_name,
521
+ get_xfrom_trad(strategy, node, "relevance", SURVEY_MAP),
522
+ node.help,
523
+ df_survey,
524
+ df_choice)
506
525
  add_calculate(calculates, node)
507
526
  if node.group != cur_group and not isinstance(node, TriccNodeSelectOption):
508
527
  return False
@@ -530,10 +549,14 @@ def generate_xls_form_export(
530
549
  ):
531
550
  df_choice.loc[len(df_choice)] = values
532
551
  elif isinstance(node, TriccNodeMoreInfo):
533
- df_survey.loc[len(df_survey)] = get_more_info_select(strategy, node)
534
- df_survey.loc[len(df_survey)] = get_more_info_message(strategy, node)
535
- if len(df_choice[(df_choice["list_name"] == "more_info")]) == 0:
536
- df_choice.loc[len(df_choice)] = get_more_info_choice(strategy)
552
+ inject_more_info(
553
+ strategy,
554
+ get_export_name(node),
555
+ get_xfrom_trad(strategy, node.parent, "relevance", SURVEY_MAP),
556
+ node.label,
557
+ df_survey,
558
+ df_choice
559
+ )
537
560
  elif node.tricc_type in ODK_TRICC_TYPE_MAP and ODK_TRICC_TYPE_MAP[node.tricc_type] is not None:
538
561
  if ODK_TRICC_TYPE_MAP[node.tricc_type] == "calculate":
539
562
  values = []
@@ -560,6 +583,16 @@ def generate_xls_form_export(
560
583
  logger.warning("node {} have an unmapped type {}".format(node.get_name(), node.tricc_type))
561
584
  else:
562
585
  logger.warning("node {} have an unsupported type {}".format(node.get_name(), node.tricc_type))
586
+ if not help_before and getattr(node, 'help', None):
587
+ base_name=f"{get_export_name(node)}_more_info"
588
+ inject_more_info(
589
+ strategy,
590
+ base_name,
591
+ get_xfrom_trad(strategy, node, "relevance", SURVEY_MAP),
592
+ node.help,
593
+ df_survey,
594
+ df_choice
595
+ )
563
596
  # continue walk °
564
597
  return True
565
598
  return False
@@ -640,6 +640,7 @@ class XLSFormCHTStrategy(XLSFormCDSSStrategy):
640
640
  df_settings.to_excel(writer, sheet_name="settings", index=False)
641
641
  writer.close()
642
642
  # pause
643
+ logger.info("generating the task and after pause questionnaires")
643
644
  ends = []
644
645
  for p in self.project.pages.values():
645
646
  p_ends = list(
@@ -56,6 +56,9 @@ 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
+
59
62
 
60
63
  def merge_node(from_node, to_node):
61
64
  if from_node.activity != to_node.activity:
@@ -405,6 +408,11 @@ def get_bridge_path(prev_nodes, node=None, edge_only=False):
405
408
  calc = TriccNodeDisplayBridge(**data)
406
409
  else:
407
410
  calc = TriccNodeBridge(**data)
411
+ if node:
412
+ priority = getattr(node, 'priority', None)
413
+ if priority:
414
+ calc.priority = priority
415
+
408
416
  return calc
409
417
 
410
418
 
@@ -968,6 +976,7 @@ def walktrhough_tricc_node_processed_stached(
968
976
  warn=False,
969
977
  node_path=[],
970
978
  process=None,
979
+ loop_count=0,
971
980
  **kwargs,
972
981
  ):
973
982
  ended_activity = False
@@ -1133,7 +1142,10 @@ def walktrhough_tricc_node_processed_stached(
1133
1142
  if nn not in stashed_nodes:
1134
1143
  stashed_nodes.insert_at_top(nn)
1135
1144
  if not recursive:
1136
- reorder_node_list(stashed_nodes, node.group, processed_nodes)
1145
+ global _last_reordered_group
1146
+ if _last_reordered_group != node.group:
1147
+ reorder_node_list(stashed_nodes, node.group, processed_nodes)
1148
+ _last_reordered_group = node.group
1137
1149
 
1138
1150
  else:
1139
1151
  if prev_process and process and prev_process != process[0]:
@@ -1280,7 +1292,7 @@ def stashed_node_func(node, callback, recursive=False, **kwargs):
1280
1292
 
1281
1293
 
1282
1294
  # check if the all the prev nodes are processed
1283
- def is_ready_to_process(in_node, processed_nodes, strict=True, local=False):
1295
+ def is_ready_to_process(in_node, processed_nodes, strict=True, local=False, loop_count=0):
1284
1296
  if isinstance(in_node, TriccNodeSelectOption):
1285
1297
  node = in_node.select
1286
1298
  elif isinstance(in_node, (TriccNodeActivityStart, TriccNodeMainStart)):
@@ -1291,36 +1303,38 @@ def is_ready_to_process(in_node, processed_nodes, strict=True, local=False):
1291
1303
  if hasattr(node, "prev_nodes"):
1292
1304
  # ensure the previous node of the select are processed, not the option prev nodes
1293
1305
  for prev_node in node.prev_nodes:
1294
- if is_prev_processed(prev_node, node, processed_nodes, local) is False:
1306
+ if is_prev_processed(prev_node, node, processed_nodes, local, loop_count) is False:
1295
1307
  return False
1296
1308
  return True
1297
1309
 
1298
1310
 
1299
- def is_prev_processed(prev_node, node, processed_nodes, local):
1311
+ def is_prev_processed(prev_node, node, processed_nodes, local, loop_count=0):
1300
1312
  if hasattr(prev_node, "select"):
1301
- return is_prev_processed(prev_node.select, node, processed_nodes, local)
1313
+ return is_prev_processed(prev_node.select, node, processed_nodes, local, loop_count)
1302
1314
  if prev_node not in processed_nodes and (not local):
1303
- if isinstance(prev_node, TriccNodeExclusive):
1304
- iterator = iter(prev_node.prev_nodes)
1305
- p_n_node = next(iterator)
1306
- logger.debug(
1307
- "is_ready_to_process:failed:via_excl: {} - {} > {} {}:{}".format(
1308
- get_data_for_log(p_n_node), prev_node.get_name(), node.__class__, node.get_name(), node.instance
1315
+ # Only log detailed failures when we suspect dependency loops (loop_count > 5)
1316
+ if loop_count > 5:
1317
+ if isinstance(prev_node, TriccNodeExclusive):
1318
+ iterator = iter(prev_node.prev_nodes)
1319
+ p_n_node = next(iterator)
1320
+ logger.debug(
1321
+ "is_ready_to_process:failed:via_excl: {} - {} > {} {}:{}".format(
1322
+ get_data_for_log(p_n_node), prev_node.get_name(), node.__class__, node.get_name(), node.instance
1323
+ )
1309
1324
  )
1310
- )
1311
1325
 
1312
- else:
1313
- logger.debug(
1314
- "is_ready_to_process:failed: {} -> {} {}:{}".format(
1315
- get_data_for_log(prev_node), node.__class__, node.get_name(), node.instance
1326
+ else:
1327
+ logger.debug(
1328
+ "is_ready_to_process:failed: {} -> {} {}:{}".format(
1329
+ get_data_for_log(prev_node), node.__class__, node.get_name(), node.instance
1330
+ )
1316
1331
  )
1317
- )
1318
1332
 
1319
- logger.debug(
1320
- "prev node node {}:{} for node {} not in processed".format(
1321
- prev_node.__class__, prev_node.get_name(), node.get_name()
1333
+ logger.debug(
1334
+ "prev node node {}:{} for node {} not in processed".format(
1335
+ prev_node.__class__, prev_node.get_name(), node.get_name()
1336
+ )
1322
1337
  )
1323
- )
1324
1338
  return False
1325
1339
  return True
1326
1340
 
@@ -1753,9 +1767,12 @@ def reorder_node_list(node_list, group, processed_nodes):
1753
1767
  return MAP_PRIORITIES[node.id]
1754
1768
  if isinstance(node, (TriccNodeActivityStart, TriccNodeMainStart)):
1755
1769
  return get_priority(node.activity)
1770
+ if isinstance(node, (TriccNodeSelectOption)):
1771
+ return get_priority(node.select)
1756
1772
 
1757
1773
  # Cache attributes to avoid repeated getattr calls
1758
- priority = int(getattr(node, "priority", 0) or 0)
1774
+ explicit_priority = getattr(node, "priority", None)
1775
+ priority = int(explicit_priority or 0)
1759
1776
  node_group = getattr(node, "group", None)
1760
1777
  activity = getattr(node, "activity", None)
1761
1778
 
@@ -1785,7 +1802,7 @@ def reorder_node_list(node_list, group, processed_nodes):
1785
1802
  elif issubclass(node.__class__, TriccRhombusMixIn):
1786
1803
  priority += RHOMBUS_PRIORITY_TO_UP
1787
1804
 
1788
- if node.prev_nodes:
1805
+ if node.prev_nodes and not explicit_priority and not isinstance(node, TriccNodeMainStart):
1789
1806
  priority = max(priority, *[get_priority(p) for p in node.prev_nodes])
1790
1807
 
1791
1808
  MAP_PRIORITIES[node.id] = priority
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tricc-oo
3
- Version: 1.6.14
3
+ Version: 1.6.16
4
4
  Summary: Python library that converts CDSS L2 in L3
5
5
  Project-URL: Homepage, https://github.com/SwissTPH/tricc
6
6
  Project-URL: Issues, https://github.com/SwissTPH/tricc/issues
@@ -9,7 +9,7 @@ tricc_oo/converters/datadictionnary.py,sha256=JasqlLKiZzKdidsA1xc2SJ_Af1Xr6A3sKf
9
9
  tricc_oo/converters/drawio_type_map.py,sha256=Zp8J9iHNSJkIVrmRSM0_d4vA1X8wFPLKb8nCMPUMXKU,9114
10
10
  tricc_oo/converters/tricc_to_xls_form.py,sha256=39hwWgYNitGE-AuKtjUwNLz39tEpwc7nd9gT_gw5wjc,3842
11
11
  tricc_oo/converters/utils.py,sha256=JZrtrvvOfXwdkw49pKauzinOcauWwsy-CVcw36TjyLo,1684
12
- tricc_oo/converters/xml_to_tricc.py,sha256=ea8LNEPDe32q74AJCbEjxaLt_Po47oH45K_G8fo7TzE,40388
12
+ tricc_oo/converters/xml_to_tricc.py,sha256=6cl0X2cHACVq56cCd9ZHj1ixpsBYSu0ruSKJSQH6ZZI,40570
13
13
  tricc_oo/converters/cql/cqlLexer.py,sha256=8HArbRphcrpnAG4uogJ2rHv4tc1WLzjN0B1uFeYILAc,49141
14
14
  tricc_oo/converters/cql/cqlListener.py,sha256=fA7-8DcS2Q69ckwjdg57-OfFHBxjTZFdoSKrtw7Hffc,57538
15
15
  tricc_oo/converters/cql/cqlParser.py,sha256=x3KdrwX9nwENSEJ5Ex7_l5NMnu3kWBO0uLdYu4moTq0,414745
@@ -25,7 +25,7 @@ tricc_oo/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
25
25
  tricc_oo/parsers/xml.py,sha256=uzkb1y18MHfqVFmZqVh0sKT4cx6u0-NcAT_lV_gHBt8,4208
26
26
  tricc_oo/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  tricc_oo/serializers/planuml.py,sha256=t57587-6L3aDncpHh58lS77Zft8yxDE9DPtXx2BeUSU,132
28
- tricc_oo/serializers/xls_form.py,sha256=ydaD5l_CsMEhJlSO0XvXPdxrwsDw4HiRjTOPHogTQdw,23071
28
+ tricc_oo/serializers/xls_form.py,sha256=E0VKcAXoVvGfinMZXOmo-90uypjsGAKS2S3-mtvAT7I,24215
29
29
  tricc_oo/strategies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  tricc_oo/strategies/input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  tricc_oo/strategies/input/base_input_strategy.py,sha256=BEODXS74na1QRRcJVQ4cxiD8F7uRqaLyhE3QzKpGVvk,3891
@@ -38,14 +38,14 @@ tricc_oo/strategies/output/openmrs_form.py,sha256=ne6TwAyhafR-WDs27QTKKFl85VD5si
38
38
  tricc_oo/strategies/output/spice.py,sha256=QMeoismVC3PdbvwTK0PtUjWX9jl9780fbQIXn76fMXw,10761
39
39
  tricc_oo/strategies/output/xls_form.py,sha256=_pNTND7n-55EjRphJ1hSVtRYa-UkXlmwpam2OKQ8o_w,30860
40
40
  tricc_oo/strategies/output/xlsform_cdss.py,sha256=X00Lt5MzV8TX14dR4dFI1MqllI5S1e13bKbeysWM9uA,17435
41
- tricc_oo/strategies/output/xlsform_cht.py,sha256=Zy8aggR1sTBP0b33RGbfUpk8pRppI1LGQEif4E1l49A,28523
41
+ tricc_oo/strategies/output/xlsform_cht.py,sha256=0wrZ_Ez41D-SciXoBq4Pn4o1bK1ofUxXqbTjDoQuCGE,28597
42
42
  tricc_oo/strategies/output/xlsform_cht_hf.py,sha256=xm6SKirV3nMZvM2w54_zJcXAeAgAkq-EEqGEjnOWv6c,988
43
43
  tricc_oo/visitors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- tricc_oo/visitors/tricc.py,sha256=QkVZpmDvSrMbMQeCxVn15zSk3iH-3-e-udMys96JkXE,110923
44
+ tricc_oo/visitors/tricc.py,sha256=ArvDNcuzIQNJpYyT1vB_B9Gxc2m5YAxg9ss_orpMqK0,111780
45
45
  tricc_oo/visitors/utils.py,sha256=j83aAq5s5atXi3OC0jc_uJd54a8XrHHmizeeEbWZQJg,421
46
46
  tricc_oo/visitors/xform_pd.py,sha256=ryAnI3V9x3eTmJ2LNsUZfvl0_yfCqo6oBgeSu-WPqaE,9613
47
- tricc_oo-1.6.14.dist-info/licenses/LICENSE,sha256=Pz2eACSxkhsGfW9_iN60pgy-enjnbGTj8df8O3ebnQQ,16726
48
- tricc_oo-1.6.14.dist-info/METADATA,sha256=_WkaLTsN1Yj8koCLVrOmdY9egk06du90gsMqRCcQ0Js,8600
49
- tricc_oo-1.6.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
50
- tricc_oo-1.6.14.dist-info/top_level.txt,sha256=NvbfMNAiy9m4b1unBsqpeOQWh4IgA1Xa33BtKA4abxk,15
51
- tricc_oo-1.6.14.dist-info/RECORD,,
47
+ tricc_oo-1.6.16.dist-info/licenses/LICENSE,sha256=Pz2eACSxkhsGfW9_iN60pgy-enjnbGTj8df8O3ebnQQ,16726
48
+ tricc_oo-1.6.16.dist-info/METADATA,sha256=9eOqHUBcjhaviC0zU-JT-NYWTY-yc6kq3r8iv6qbGoE,8600
49
+ tricc_oo-1.6.16.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
50
+ tricc_oo-1.6.16.dist-info/top_level.txt,sha256=NvbfMNAiy9m4b1unBsqpeOQWh4IgA1Xa33BtKA4abxk,15
51
+ tricc_oo-1.6.16.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5