tricc-oo 1.6.12__tar.gz → 1.6.14__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 (57) hide show
  1. {tricc_oo-1.6.12/tricc_oo.egg-info → tricc_oo-1.6.14}/PKG-INFO +1 -1
  2. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/pyproject.toml +1 -1
  3. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/codesystem_to_ocl.py +4 -4
  4. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/datadictionnary.py +1 -1
  5. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/drawio_type_map.py +11 -11
  6. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/xml_to_tricc.py +30 -15
  7. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/serializers/xls_form.py +59 -2
  8. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/dhis2_form.py +15 -211
  9. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/fhir_form.py +1 -1
  10. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/xlsform_cht.py +1 -1
  11. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/visitors/tricc.py +47 -65
  12. {tricc_oo-1.6.12 → tricc_oo-1.6.14/tricc_oo.egg-info}/PKG-INFO +1 -1
  13. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo.egg-info/SOURCES.txt +0 -1
  14. tricc_oo-1.6.12/tests/test_build.py +0 -260
  15. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/LICENSE +0 -0
  16. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/README.md +0 -0
  17. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/setup.cfg +0 -0
  18. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tests/build.py +0 -0
  19. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tests/test_cql.py +0 -0
  20. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tests/to_ocl.py +0 -0
  21. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/__init__.py +0 -0
  22. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/__init__.py +0 -0
  23. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/cql/cqlLexer.py +0 -0
  24. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/cql/cqlListener.py +0 -0
  25. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/cql/cqlParser.py +0 -0
  26. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
  27. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/cql_to_operation.py +0 -0
  28. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/tricc_to_xls_form.py +0 -0
  29. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/converters/utils.py +0 -0
  30. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/models/__init__.py +0 -0
  31. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/models/base.py +0 -0
  32. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/models/calculate.py +0 -0
  33. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/models/lang.py +0 -0
  34. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/models/ocl.py +0 -0
  35. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/models/ordered_set.py +0 -0
  36. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/models/tricc.py +0 -0
  37. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/parsers/__init__.py +0 -0
  38. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/parsers/xml.py +0 -0
  39. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/serializers/__init__.py +0 -0
  40. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/serializers/planuml.py +0 -0
  41. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/__init__.py +0 -0
  42. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/input/__init__.py +0 -0
  43. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/input/base_input_strategy.py +0 -0
  44. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/input/drawio.py +0 -0
  45. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/base_output_strategy.py +0 -0
  46. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/html_form.py +0 -0
  47. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/openmrs_form.py +0 -0
  48. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/spice.py +0 -0
  49. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/xls_form.py +0 -0
  50. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
  51. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
  52. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/visitors/__init__.py +0 -0
  53. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/visitors/utils.py +0 -0
  54. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo/visitors/xform_pd.py +0 -0
  55. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo.egg-info/dependency_links.txt +0 -0
  56. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/tricc_oo.egg-info/requires.txt +0 -0
  57. {tricc_oo-1.6.12 → tricc_oo-1.6.14}/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.12
3
+ Version: 1.6.14
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.12"
7
+ version = "1.6.14"
8
8
  description = "Python library that converts CDSS L2 in L3"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -31,16 +31,16 @@ def extract_properties_metadata(fhir_cs: CodeSystem) -> Dict[str, Dict]:
31
31
 
32
32
  property_types[prop.code] = {
33
33
  "name": prop.code,
34
- "datatype": ocl_type,
34
+ "dataType": ocl_type,
35
35
  "description": prop.description if hasattr(prop, "description") else "",
36
36
  }
37
37
  return property_types
38
38
 
39
39
 
40
40
  def get_fhir_concept_datatype(concept):
41
- datatype = extract_concept_properties(concept, ["datatype"])
41
+ datatype = extract_concept_properties(concept, ["dataType"])
42
42
  if datatype:
43
- return datatype["datatype"]
43
+ return datatype["dataType"]
44
44
  else:
45
45
  return OclConstants.DATA_TYPE_NONE
46
46
 
@@ -84,7 +84,7 @@ def get_attributes_from_concept_properties(concept, property_types: Dict) -> Lis
84
84
  "type": "Attribute",
85
85
  "attribute_type": code,
86
86
  "value": value,
87
- "value_type": property_types[code]["datatype"],
87
+ "value_type": property_types[code]["dataType"],
88
88
  }
89
89
  )
90
90
  return attributes
@@ -103,7 +103,7 @@ def check_and_add_concept(code_system: CodeSystem, code: str, display: str, attr
103
103
  # TODO support other type of Codesystem Concept Property Value
104
104
  existing_attributes
105
105
  if p.valueString != v:
106
- logger.warning(f"conflicting value for property {k}: {p.valueString} != {v}")
106
+ logger.warning(f"conflicting value for concept `{concept.code}` property ` {k}`: {p.valueString} != {v}")
107
107
  if not existing_attributes:
108
108
  new_concept.property.append(CodeSystemConceptProperty(code=k, valueString=v))
109
109
 
@@ -47,7 +47,7 @@ TYPE_MAP = {
47
47
  },
48
48
  TriccNodeType.note: {
49
49
  "objects": ["UserObject", "object"],
50
- "attributes": ["relevance", "priority", "context_type"],
50
+ "attributes": ["relevance", "priority", "concept_type"],
51
51
  "mandatory_attributes": ["label", "name"],
52
52
  "model": TriccNodeNote,
53
53
  },
@@ -76,7 +76,7 @@ TYPE_MAP = {
76
76
  "priority",
77
77
  "trigger",
78
78
  "default",
79
- "context_type",
79
+ "concept_type",
80
80
  ],
81
81
  "mandatory_attributes": ["label", "name", "list_name"],
82
82
  "model": TriccNodeSelectOne,
@@ -94,7 +94,7 @@ TYPE_MAP = {
94
94
  "priority",
95
95
  "trigger",
96
96
  "default",
97
- "context_type",
97
+ "concept_type",
98
98
  ],
99
99
  "mandatory_attributes": ["label", "name", "list_name"],
100
100
  "model": TriccNodeSelectMultiple,
@@ -112,7 +112,7 @@ TYPE_MAP = {
112
112
  "priority",
113
113
  "trigger",
114
114
  "default",
115
- "context_type",
115
+ "concept_type",
116
116
  ],
117
117
  "mandatory_attributes": ["label", "name"],
118
118
  "model": TriccNodeDecimal,
@@ -130,7 +130,7 @@ TYPE_MAP = {
130
130
  "priority",
131
131
  "trigger",
132
132
  "default",
133
- "context_type",
133
+ "concept_type",
134
134
  ],
135
135
  "mandatory_attributes": ["label", "name"],
136
136
  "model": TriccNodeInteger,
@@ -145,7 +145,7 @@ TYPE_MAP = {
145
145
  "default",
146
146
  "constraint",
147
147
  "constraint_message",
148
- "context_type",
148
+ "concept_type",
149
149
  ],
150
150
  "mandatory_attributes": ["label", "name"],
151
151
  "model": TriccNodeText,
@@ -160,7 +160,7 @@ TYPE_MAP = {
160
160
  "default",
161
161
  "constraint",
162
162
  "constraint_message",
163
- "context_type",
163
+ "concept_type",
164
164
  ],
165
165
  "mandatory_attributes": ["label", "name"],
166
166
  "model": TriccNodeDate,
@@ -183,7 +183,7 @@ TYPE_MAP = {
183
183
  "save",
184
184
  "reference",
185
185
  "trigger",
186
- "context_type",
186
+ "concept_type",
187
187
  "remote_reference",
188
188
  ],
189
189
  "mandatory_attributes": ["name", "label"],
@@ -217,7 +217,7 @@ TYPE_MAP = {
217
217
  },
218
218
  TriccNodeType.not_available: {
219
219
  "objects": ["UserObject", "object"],
220
- "attributes": ["context_type"],
220
+ "attributes": ["concept_type"],
221
221
  "mandatory_attributes": ["label", "name", "list_name"],
222
222
  "model": TriccNodeSelectNotAvailable,
223
223
  },
@@ -233,7 +233,7 @@ TYPE_MAP = {
233
233
  "priority",
234
234
  "trigger",
235
235
  "default",
236
- "context_type",
236
+ "concept_type",
237
237
  ],
238
238
  "mandatory_attributes": ["label", "name", "list_name"],
239
239
  "model": TriccNodeSelectYesNo,
@@ -295,7 +295,7 @@ TYPE_MAP = {
295
295
  },
296
296
  TriccNodeType.input: {
297
297
  "objects": ["UserObject", "object"],
298
- "attributes": ["save", "reference", "datatype", "context_type"],
298
+ "attributes": ["save", "reference", "data_type", "concept_type"],
299
299
  "mandatory_attributes": ["name", "label"],
300
300
  "model": TriccNodeInput,
301
301
  },
@@ -128,7 +128,7 @@ def create_activity(diagram, media_path, project):
128
128
  for n in nodes.values():
129
129
 
130
130
  if (
131
- issubclass(n.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase))
131
+ issubclass(n.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase, TriccNodeInput))
132
132
  and not isinstance(n, (TriccRhombusMixIn, TriccNodeRhombus, TriccNodeDisplayBridge))
133
133
  and not n.name.startswith("label_") # FIXME
134
134
  ):
@@ -139,7 +139,7 @@ def create_activity(diagram, media_path, project):
139
139
  system,
140
140
  n.select.name,
141
141
  n.label,
142
- {"datatype": "Boolean", "contextType": get_context_type(n)},
142
+ {"dataType": "Boolean", "conceptType": get_concept_type(n)},
143
143
  )
144
144
  elif not isinstance(n, TriccNodeSelectNotAvailable):
145
145
  add_concept(
@@ -148,8 +148,20 @@ def create_activity(diagram, media_path, project):
148
148
  n.name,
149
149
  n.label,
150
150
  {
151
- "datatype": get_data_type(n.tricc_type),
152
- "contextType": get_context_type(n),
151
+ "dataType": get_data_type(n.tricc_type),
152
+ "conceptType": get_concept_type(n),
153
+ },
154
+ )
155
+ elif not issubclass(n.__class__, TriccNodeCalculate):
156
+ system = n.name.split(".")[0] if "." in n.name else "calculate"
157
+ add_concept(
158
+ project.code_systems,
159
+ system,
160
+ n.name,
161
+ n.label,
162
+ {
163
+ "dataType": get_data_type(n.tricc_type),
164
+ "conceptType": get_concept_type(n),
153
165
  },
154
166
  )
155
167
  if getattr(n, "save", None):
@@ -160,8 +172,8 @@ def create_activity(diagram, media_path, project):
160
172
  n.save,
161
173
  n.label,
162
174
  {
163
- "datatype": get_data_type(n.tricc_type),
164
- "contextType": get_context_type(n),
175
+ "dataType": get_data_type(n.tricc_type),
176
+ "conceptType": get_concept_type(n),
165
177
  },
166
178
  )
167
179
 
@@ -175,7 +187,7 @@ def create_activity(diagram, media_path, project):
175
187
  # link back the activity
176
188
  activity.root.activity = activity
177
189
  manage_dangling_calculate(activity)
178
-
190
+ # assign the process
179
191
  if activity is not None:
180
192
  if activity.root is not None:
181
193
  project.pages[activity.id] = activity
@@ -197,6 +209,7 @@ def create_activity(diagram, media_path, project):
197
209
  )
198
210
  if images:
199
211
  project.images += images
212
+ # Assign parent to NotAvailable
200
213
  for node in list(
201
214
  filter(
202
215
  lambda p_node: isinstance(p_node, TriccNodeSelectNotAvailable),
@@ -477,10 +490,10 @@ def set_additional_attributes(attribute_names, elm, node):
477
490
  setattr(node, attributename, attribute)
478
491
 
479
492
 
480
- def get_context_type(node):
481
- context_type = getattr(node, "context_type", None)
482
- if context_type:
483
- return context_type
493
+ def get_concept_type(node):
494
+ concept_type = getattr(node, "concept_type", None)
495
+ if concept_type:
496
+ return concept_type
484
497
  if isinstance(node, TriccNodeSelectMultiple):
485
498
  return "Question"
486
499
  elif isinstance(node, TriccNodeSelectOption):
@@ -535,7 +548,7 @@ def get_select_options(diagram, select_node, nodes):
535
548
  activity=select_node.activity,
536
549
  group=select_node.group,
537
550
  )
538
- set_additional_attributes(["save", "relevance", "context_type"], elm, option)
551
+ set_additional_attributes(["save", "relevance", "concept_type"], elm, option)
539
552
  load_expressions(option)
540
553
  options[i] = option
541
554
  nodes[id] = option
@@ -802,9 +815,11 @@ def set_mandatory_attribute(elm, mandatory_attributes, diagram=None):
802
815
  id = elm.attrib.get("id")
803
816
  attribute_value = _get_name(name, id, diagram_id)
804
817
  elif attributes == "list_name":
805
- name = elm.attrib.get("name")
806
- id = elm.attrib.get("id")
807
- attribute_value = TRICC_LIST_NAME.format(clean_str(_get_name(name, id, diagram_id), replace_dots=True))
818
+ attribute_value = elm.attrib.get("list_name", None)
819
+ if not attribute_value:
820
+ name = elm.attrib.get("name")
821
+ id = elm.attrib.get("id")
822
+ attribute_value = TRICC_LIST_NAME.format(clean_str(_get_name(name, id, diagram_id), replace_dots=True))
808
823
  else:
809
824
  attribute_value = elm.attrib.get(attributes)
810
825
  if attribute_value is None:
@@ -32,6 +32,7 @@ from tricc_oo.visitors.tricc import (
32
32
  get_applicability_expression,
33
33
  get_prev_instance_skip_expression,
34
34
  get_process_skip_expression,
35
+ process_operation_reference,
35
36
  )
36
37
 
37
38
  logger = logging.getLogger("default")
@@ -64,7 +65,36 @@ def start_group(
64
65
  groups[name] = 0
65
66
  relevance = relevance and cur_group.relevance is not None and cur_group.relevance != ""
66
67
  past_instances = len(getattr(cur_group.base_instance, "instances", []))
68
+ group_calc_required = relevance is not None and (len(str(relevance)) > 100 or past_instances > 1)
67
69
  calc = None
70
+ if group_calc_required and getattr(cur_group.relevance, 'operator', None) != TriccOperator.ISTRUE:
71
+
72
+ calc = TriccNodeCalculate(
73
+ id=generate_id(get_export_group_name(name)),
74
+ group=cur_group.group,
75
+ activity=cur_group.activity,
76
+ name=get_export_group_name(name),
77
+ expression=cur_group.relevance
78
+ )
79
+
80
+ if calc not in cur_group.activity.calculates:
81
+ process_reference(
82
+ calc,
83
+ processed_nodes,
84
+ calculates=kwargs.get('calculates', None),
85
+ used_calculates=kwargs.get('used_calculates', None),
86
+ replace_reference=True,
87
+ warn=False,
88
+ codesystems=kwargs.get('codesystems', None)
89
+ )
90
+ cur_group.activity.calculates.append(calc)
91
+ cur_group.activity.nodes[calc.id] = calc
92
+ processed_nodes.add(calc)
93
+
94
+ cur_group.relevance = TriccOperation(
95
+ TriccOperator.ISTRUE,
96
+ [calc]
97
+ )
68
98
 
69
99
  relevance_expression = cur_group.relevance
70
100
  relevance_expression = get_applicability_expression(cur_group, processed_nodes, process, relevance_expression)
@@ -74,7 +104,18 @@ def start_group(
74
104
  if not relevance:
75
105
  relevance_expression_str = ""
76
106
  elif isinstance(relevance_expression, (TriccOperation, TriccStatic)):
77
- relevance_expression_str = strategy.get_tricc_operation_expression(relevance_expression)
107
+ relevance_expression = process_operation_reference(
108
+ relevance_expression,
109
+ cur_group,
110
+ processed_nodes=processed_nodes,
111
+ calculates=kwargs.get('calculates', None),
112
+ used_calculates=kwargs.get('used_calculates', None),
113
+ replace_reference=True,
114
+ warn=False,
115
+ codesystems=kwargs.get('codesystems', None),
116
+ ) or relevance_expression
117
+ if relevance_expression:
118
+ relevance_expression_str = strategy.get_tricc_operation_expression(relevance_expression)
78
119
 
79
120
  # group
80
121
  values = []
@@ -95,7 +136,23 @@ def start_group(
95
136
  values.append(get_xfrom_trad(strategy, cur_group, column, SURVEY_MAP))
96
137
  df_survey.loc[len(df_survey)] = values
97
138
 
98
- # Group calculates are now created during process_calculate phase
139
+ # calc
140
+ if calc and len(df_calculate[df_calculate["name"] == get_export_group_name(name)]) == 0:
141
+ calc_values = []
142
+ for column in SURVEY_MAP:
143
+ if column == "type":
144
+ calc_values.append("calculate")
145
+ elif column == "name":
146
+ value = get_export_name(calc)
147
+ calc_values.append(value)
148
+ elif column == "calculation":
149
+ calc_values.append(f"number({strategy.get_tricc_operation_expression(calc.expression)})")
150
+ elif column == "relevance":
151
+ calc_values.append("")
152
+ else:
153
+ calc_values.append(get_xfrom_trad(strategy, cur_group, column, SURVEY_MAP))
154
+
155
+ df_calculate.loc[len(df_calculate)] = calc_values
99
156
 
100
157
 
101
158
  # def add_background_color(input_string, color):