tricc-oo 1.6.15__tar.gz → 1.6.16__tar.gz

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.
Files changed (56) hide show
  1. {tricc_oo-1.6.15/tricc_oo.egg-info → tricc_oo-1.6.16}/PKG-INFO +1 -1
  2. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/pyproject.toml +1 -1
  3. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/xml_to_tricc.py +17 -17
  4. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/serializers/xls_form.py +48 -15
  5. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/xlsform_cht.py +1 -0
  6. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/visitors/tricc.py +33 -23
  7. {tricc_oo-1.6.15 → tricc_oo-1.6.16/tricc_oo.egg-info}/PKG-INFO +1 -1
  8. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/LICENSE +0 -0
  9. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/README.md +0 -0
  10. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/setup.cfg +0 -0
  11. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tests/build.py +0 -0
  12. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tests/test_cql.py +0 -0
  13. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tests/to_ocl.py +0 -0
  14. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/__init__.py +0 -0
  15. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/__init__.py +0 -0
  16. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/codesystem_to_ocl.py +0 -0
  17. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/cql/cqlLexer.py +0 -0
  18. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/cql/cqlListener.py +0 -0
  19. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/cql/cqlParser.py +0 -0
  20. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
  21. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/cql_to_operation.py +0 -0
  22. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/datadictionnary.py +0 -0
  23. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/drawio_type_map.py +0 -0
  24. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/tricc_to_xls_form.py +0 -0
  25. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/converters/utils.py +0 -0
  26. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/models/__init__.py +0 -0
  27. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/models/base.py +0 -0
  28. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/models/calculate.py +0 -0
  29. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/models/lang.py +0 -0
  30. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/models/ocl.py +0 -0
  31. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/models/ordered_set.py +0 -0
  32. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/models/tricc.py +0 -0
  33. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/parsers/__init__.py +0 -0
  34. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/parsers/xml.py +0 -0
  35. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/serializers/__init__.py +0 -0
  36. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/serializers/planuml.py +0 -0
  37. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/__init__.py +0 -0
  38. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/input/__init__.py +0 -0
  39. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/input/base_input_strategy.py +0 -0
  40. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/input/drawio.py +0 -0
  41. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/base_output_strategy.py +0 -0
  42. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/dhis2_form.py +0 -0
  43. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/fhir_form.py +0 -0
  44. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/html_form.py +0 -0
  45. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/openmrs_form.py +0 -0
  46. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/spice.py +0 -0
  47. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/xls_form.py +0 -0
  48. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
  49. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
  50. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/visitors/__init__.py +0 -0
  51. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/visitors/utils.py +0 -0
  52. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo/visitors/xform_pd.py +0 -0
  53. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo.egg-info/SOURCES.txt +0 -0
  54. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo.egg-info/dependency_links.txt +0 -0
  55. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo.egg-info/requires.txt +0 -0
  56. {tricc_oo-1.6.15 → tricc_oo-1.6.16}/tricc_oo.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tricc-oo
3
- Version: 1.6.15
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tricc-oo"
7
- version = "1.6.15"
7
+ version = "1.6.16"
8
8
  description = "Python library that converts CDSS L2 in L3"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -636,23 +636,23 @@ def enrich_node(diagram, media_path, edge, node, activity, help_before=False):
636
636
  # get node and process type
637
637
  type, message = get_message(diagram, edge.source_external_id)
638
638
  if type is not 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
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
656
656
 
657
657
  if type in (TriccNodeType.start, TriccNodeType.activity_start):
658
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:
@@ -973,6 +976,7 @@ def walktrhough_tricc_node_processed_stached(
973
976
  warn=False,
974
977
  node_path=[],
975
978
  process=None,
979
+ loop_count=0,
976
980
  **kwargs,
977
981
  ):
978
982
  ended_activity = False
@@ -1138,7 +1142,10 @@ def walktrhough_tricc_node_processed_stached(
1138
1142
  if nn not in stashed_nodes:
1139
1143
  stashed_nodes.insert_at_top(nn)
1140
1144
  if not recursive:
1141
- 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
1142
1149
 
1143
1150
  else:
1144
1151
  if prev_process and process and prev_process != process[0]:
@@ -1285,7 +1292,7 @@ def stashed_node_func(node, callback, recursive=False, **kwargs):
1285
1292
 
1286
1293
 
1287
1294
  # check if the all the prev nodes are processed
1288
- 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):
1289
1296
  if isinstance(in_node, TriccNodeSelectOption):
1290
1297
  node = in_node.select
1291
1298
  elif isinstance(in_node, (TriccNodeActivityStart, TriccNodeMainStart)):
@@ -1296,36 +1303,38 @@ def is_ready_to_process(in_node, processed_nodes, strict=True, local=False):
1296
1303
  if hasattr(node, "prev_nodes"):
1297
1304
  # ensure the previous node of the select are processed, not the option prev nodes
1298
1305
  for prev_node in node.prev_nodes:
1299
- 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:
1300
1307
  return False
1301
1308
  return True
1302
1309
 
1303
1310
 
1304
- def is_prev_processed(prev_node, node, processed_nodes, local):
1311
+ def is_prev_processed(prev_node, node, processed_nodes, local, loop_count=0):
1305
1312
  if hasattr(prev_node, "select"):
1306
- 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)
1307
1314
  if prev_node not in processed_nodes and (not local):
1308
- if isinstance(prev_node, TriccNodeExclusive):
1309
- iterator = iter(prev_node.prev_nodes)
1310
- p_n_node = next(iterator)
1311
- logger.debug(
1312
- "is_ready_to_process:failed:via_excl: {} - {} > {} {}:{}".format(
1313
- 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
+ )
1314
1324
  )
1315
- )
1316
1325
 
1317
- else:
1318
- logger.debug(
1319
- "is_ready_to_process:failed: {} -> {} {}:{}".format(
1320
- 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
+ )
1321
1331
  )
1322
- )
1323
1332
 
1324
- logger.debug(
1325
- "prev node node {}:{} for node {} not in processed".format(
1326
- 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
+ )
1327
1337
  )
1328
- )
1329
1338
  return False
1330
1339
  return True
1331
1340
 
@@ -1762,7 +1771,8 @@ def reorder_node_list(node_list, group, processed_nodes):
1762
1771
  return get_priority(node.select)
1763
1772
 
1764
1773
  # Cache attributes to avoid repeated getattr calls
1765
- priority = int(getattr(node, "priority", 0) or 0)
1774
+ explicit_priority = getattr(node, "priority", None)
1775
+ priority = int(explicit_priority or 0)
1766
1776
  node_group = getattr(node, "group", None)
1767
1777
  activity = getattr(node, "activity", None)
1768
1778
 
@@ -1792,7 +1802,7 @@ def reorder_node_list(node_list, group, processed_nodes):
1792
1802
  elif issubclass(node.__class__, TriccRhombusMixIn):
1793
1803
  priority += RHOMBUS_PRIORITY_TO_UP
1794
1804
 
1795
- if node.prev_nodes:
1805
+ if node.prev_nodes and not explicit_priority and not isinstance(node, TriccNodeMainStart):
1796
1806
  priority = max(priority, *[get_priority(p) for p in node.prev_nodes])
1797
1807
 
1798
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.15
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes