tricc-oo 1.6.25__tar.gz → 1.7.0.dev1__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.25/tricc_oo.egg-info → tricc_oo-1.7.0.dev1}/PKG-INFO +1 -1
  2. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/pyproject.toml +1 -1
  3. tricc_oo-1.7.0.dev1/tests/test_build.py +260 -0
  4. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tests/test_cql.py +0 -9
  5. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/codesystem_to_ocl.py +4 -4
  6. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/cql_to_operation.py +0 -1
  7. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/datadictionnary.py +2 -2
  8. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/drawio_type_map.py +11 -11
  9. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/tricc_to_xls_form.py +4 -5
  10. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/xml_to_tricc.py +34 -55
  11. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/models/base.py +1 -7
  12. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/models/tricc.py +1 -5
  13. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/serializers/xls_form.py +34 -90
  14. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/base_output_strategy.py +0 -7
  15. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/dhis2_form.py +8 -8
  16. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/openmrs_form.py +2 -2
  17. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/xls_form.py +49 -133
  18. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/xlsform_cht.py +4 -129
  19. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/visitors/tricc.py +106 -222
  20. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1/tricc_oo.egg-info}/PKG-INFO +1 -1
  21. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo.egg-info/SOURCES.txt +1 -0
  22. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/LICENSE +0 -0
  23. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/README.md +0 -0
  24. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/setup.cfg +0 -0
  25. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tests/build.py +0 -0
  26. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tests/to_ocl.py +0 -0
  27. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/__init__.py +0 -0
  28. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/__init__.py +0 -0
  29. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/cql/cqlLexer.py +0 -0
  30. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/cql/cqlListener.py +0 -0
  31. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/cql/cqlParser.py +0 -0
  32. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
  33. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/converters/utils.py +0 -0
  34. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/models/__init__.py +0 -0
  35. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/models/calculate.py +0 -0
  36. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/models/lang.py +0 -0
  37. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/models/ocl.py +0 -0
  38. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/models/ordered_set.py +0 -0
  39. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/parsers/__init__.py +0 -0
  40. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/parsers/xml.py +0 -0
  41. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/serializers/__init__.py +0 -0
  42. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/serializers/planuml.py +0 -0
  43. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/__init__.py +0 -0
  44. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/input/__init__.py +0 -0
  45. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/input/base_input_strategy.py +0 -0
  46. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/input/drawio.py +0 -0
  47. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/fhir_form.py +0 -0
  48. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/html_form.py +0 -0
  49. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/spice.py +0 -0
  50. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
  51. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
  52. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/visitors/__init__.py +0 -0
  53. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/visitors/utils.py +0 -0
  54. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo/visitors/xform_pd.py +0 -0
  55. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo.egg-info/dependency_links.txt +0 -0
  56. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/tricc_oo.egg-info/requires.txt +0 -0
  57. {tricc_oo-1.6.25 → tricc_oo-1.7.0.dev1}/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.25
3
+ Version: 1.7.0.dev1
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.25"
7
+ version = "1.7.0.dev001"
8
8
  description = "Python library that converts CDSS L2 in L3"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -0,0 +1,260 @@
1
+ import unittest
2
+ import subprocess
3
+ import sys
4
+ import os
5
+ import tempfile
6
+ import shutil
7
+ from pathlib import Path
8
+ import pandas as pd
9
+ from pyxform import create_survey_from_xls
10
+
11
+
12
+ class TestBuildScript(unittest.TestCase):
13
+ """Test cases for the build.py script with different argument combinations."""
14
+
15
+ def setUp(self):
16
+ """Set up test fixtures."""
17
+ self.test_data_dir = Path(__file__).parent / "data"
18
+ self.test_output_dir = Path(__file__).parent / "output"
19
+ self.demo_file = self.test_data_dir / "demo.drawio"
20
+
21
+ # Ensure test data exists
22
+ self.assertTrue(self.demo_file.exists(), f"Test data file {self.demo_file} does not exist")
23
+
24
+ def run_build_script(self, args):
25
+ """Helper method to run build.py with given arguments."""
26
+ cmd = [sys.executable, str(Path(__file__).parent / "build.py")] + args
27
+ result = subprocess.run(cmd, capture_output=True, text=True, cwd=Path(__file__).parent.parent)
28
+ return result
29
+
30
+ def test_basic_build_with_demo_file(self):
31
+ """Test basic build with demo.drawio file."""
32
+ with tempfile.TemporaryDirectory() as temp_dir:
33
+ args = [
34
+ "-i", str(self.demo_file),
35
+ "-o", temp_dir,
36
+ "-l", "i"
37
+ ]
38
+ result = self.run_build_script(args)
39
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
40
+
41
+ def test_build_with_directory_input(self):
42
+ """Test build with directory containing drawio files."""
43
+ with tempfile.TemporaryDirectory() as temp_dir:
44
+ args = [
45
+ "-i", str(self.test_data_dir),
46
+ "-o", temp_dir,
47
+ "-l", "i"
48
+ ]
49
+ result = self.run_build_script(args)
50
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
51
+
52
+ def test_build_with_xlsform_strategy(self):
53
+ """Test build with XLSFormStrategy (default)."""
54
+ with tempfile.TemporaryDirectory() as temp_dir:
55
+ args = [
56
+ "-i", str(self.demo_file),
57
+ "-o", temp_dir,
58
+ "-O", "XLSFormStrategy",
59
+ "-l", "i"
60
+ ]
61
+ result = self.run_build_script(args)
62
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
63
+
64
+ def test_build_with_html_strategy(self):
65
+ """Test build with HTMLStrategy."""
66
+ with tempfile.TemporaryDirectory() as temp_dir:
67
+ args = [
68
+ "-i", str(self.demo_file),
69
+ "-o", temp_dir,
70
+ "-O", "HTMLStrategy",
71
+ "-l", "i"
72
+ ]
73
+ result = self.run_build_script(args)
74
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
75
+
76
+ def test_build_with_fhir_strategy(self):
77
+ """Test build with FHIRStrategy."""
78
+ with tempfile.TemporaryDirectory() as temp_dir:
79
+ args = [
80
+ "-i", str(self.demo_file),
81
+ "-o", temp_dir,
82
+ "-O", "FHIRStrategy",
83
+ "-l", "i"
84
+ ]
85
+ result = self.run_build_script(args)
86
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
87
+
88
+ def test_build_with_dhis2_strategy(self):
89
+ """Test build with DHIS2Strategy."""
90
+ with tempfile.TemporaryDirectory() as temp_dir:
91
+ args = [
92
+ "-i", str(self.demo_file),
93
+ "-o", temp_dir,
94
+ "-O", "DHIS2Strategy",
95
+ "-l", "i"
96
+ ]
97
+ result = self.run_build_script(args)
98
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
99
+
100
+ def test_build_with_openmrs_strategy(self):
101
+ """Test build with OpenMRSStrategy."""
102
+ with tempfile.TemporaryDirectory() as temp_dir:
103
+ args = [
104
+ "-i", str(self.demo_file),
105
+ "-o", temp_dir,
106
+ "-O", "OpenMRSStrategy",
107
+ "-l", "i"
108
+ ]
109
+ result = self.run_build_script(args)
110
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
111
+
112
+ def test_build_with_cht_strategy(self):
113
+ """Test build with XLSFormCHTStrategy."""
114
+ with tempfile.TemporaryDirectory() as temp_dir:
115
+ args = [
116
+ "-i", str(self.demo_file),
117
+ "-o", temp_dir,
118
+ "-O", "XLSFormCHTStrategy",
119
+ "-l", "i"
120
+ ]
121
+ result = self.run_build_script(args)
122
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
123
+
124
+ def test_build_with_cht_hf_strategy(self):
125
+ """Test build with XLSFormCHTHFStrategy."""
126
+ with tempfile.TemporaryDirectory() as temp_dir:
127
+ args = [
128
+ "-i", str(self.demo_file),
129
+ "-o", temp_dir,
130
+ "-O", "XLSFormCHTHFStrategy",
131
+ "-l", "i"
132
+ ]
133
+ result = self.run_build_script(args)
134
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
135
+
136
+ def test_build_with_cdss_strategy(self):
137
+ """Test build with XLSFormCDSSStrategy."""
138
+ with tempfile.TemporaryDirectory() as temp_dir:
139
+ args = [
140
+ "-i", str(self.demo_file),
141
+ "-o", temp_dir,
142
+ "-O", "XLSFormCDSSStrategy",
143
+ "-l", "i"
144
+ ]
145
+ result = self.run_build_script(args)
146
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
147
+
148
+ # def test_build_with_spice_strategy(self):
149
+ # """Test build with SpiceStrategy."""
150
+ # with tempfile.TemporaryDirectory() as temp_dir:
151
+ # args = [
152
+ # "-i", str(self.demo_file),
153
+ # "-o", temp_dir,
154
+ # "-O", "SpiceStrategy",
155
+ # "-l", "i"
156
+ # ]
157
+ # result = self.run_build_script(args)
158
+ # self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
159
+
160
+ def test_build_with_debug_level(self):
161
+ """Test build with debug logging level."""
162
+ with tempfile.TemporaryDirectory() as temp_dir:
163
+ args = [
164
+ "-i", str(self.demo_file),
165
+ "-o", temp_dir,
166
+ "-l", "d"
167
+ ]
168
+ result = self.run_build_script(args)
169
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
170
+
171
+ def test_build_with_trad_option(self):
172
+ """Test build with translation option."""
173
+ with tempfile.TemporaryDirectory() as temp_dir:
174
+ args = [
175
+ "-i", str(self.demo_file),
176
+ "-o", temp_dir,
177
+ "-t",
178
+ "-l", "i"
179
+ ]
180
+ result = self.run_build_script(args)
181
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
182
+
183
+ def test_build_with_form_id(self):
184
+ """Test build with custom form ID."""
185
+ with tempfile.TemporaryDirectory() as temp_dir:
186
+ args = [
187
+ "-i", str(self.demo_file),
188
+ "-o", temp_dir,
189
+ "-d", "test_form_123",
190
+ "-l", "i"
191
+ ]
192
+ result = self.run_build_script(args)
193
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
194
+
195
+ def test_build_missing_input(self):
196
+ """Test build with missing input file."""
197
+ args = ["-o", "/tmp/test_output"]
198
+ result = self.run_build_script(args)
199
+ self.assertNotEqual(result.returncode, 0, "Build should fail with missing input")
200
+
201
+ def test_build_invalid_input_file(self):
202
+ """Test build with invalid input file."""
203
+ with tempfile.TemporaryDirectory() as temp_dir:
204
+ args = [
205
+ "-i", "/nonexistent/file.drawio",
206
+ "-o", temp_dir,
207
+ "-l", "i"
208
+ ]
209
+ result = self.run_build_script(args)
210
+ self.assertNotEqual(result.returncode, 0, "Build should fail with invalid input file")
211
+
212
+ def validate_xls_form(self, xls_path):
213
+ """Helper method to validate XLS form using ODK libraries."""
214
+ try:
215
+ # Convert XLS to XML using pyxform
216
+ survey = create_survey_from_xls(xls_path)
217
+ xml_output = survey.to_xml()
218
+
219
+ # Basic validation - check if XML was generated successfully
220
+ # In a real scenario, you might want to use odk_validate command line tool
221
+ if xml_output and len(xml_output.strip()) > 0:
222
+ return True, "Validation successful"
223
+ else:
224
+ return False, "Empty XML output"
225
+ except Exception as e:
226
+ return False, str(e)
227
+
228
+ def test_xlsform_strategy_validation(self):
229
+ """Test XLSFormStrategy output validation with ODK libraries."""
230
+ with tempfile.TemporaryDirectory() as temp_dir:
231
+ xls_output = Path(temp_dir) / "demo_tricc.xlsx"
232
+ args = [
233
+ "-i", str(self.demo_file),
234
+ "-o", temp_dir,
235
+ "-O", "XLSFormStrategy",
236
+ "-l", "i"
237
+ ]
238
+ result = self.run_build_script(args)
239
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
240
+
241
+ # Check if XLS file was created
242
+ self.assertTrue(xls_output.exists(), f"XLS file {xls_output} was not created")
243
+
244
+ def test_xlsform_cdss_strategy_validation(self):
245
+ """Test XLSFormCDSSStrategy output validation with ODK libraries."""
246
+ with tempfile.TemporaryDirectory() as temp_dir:
247
+ xls_output = Path(temp_dir) / "demo_tricc.xlsx"
248
+ args = [
249
+ "-i", str(self.demo_file),
250
+ "-o", temp_dir,
251
+ "-O", "XLSFormCDSSStrategy",
252
+ "-l", "i"
253
+ ]
254
+ result = self.run_build_script(args)
255
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
256
+
257
+
258
+
259
+ if __name__ == "__main__":
260
+ unittest.main()
@@ -26,15 +26,6 @@ class TestCql(unittest.TestCase):
26
26
  )
27
27
  self.assertEqual(str(dg_operation), str(dg_expected))
28
28
 
29
- def test_diagnosis_list(self):
30
- if_cql = 'DiagnosisList("final.TRIAGE_YELLOW", "triage_RED")'
31
- dg_operation = transform_cql_to_operation(if_cql)
32
- dg_expected = TriccOperation(
33
- operator=TriccOperator.DIAGNOSIS_LIST,
34
- reference=[TriccReference(value="final.TRIAGE_YELLOW"), TriccReference(value="triage_RED")],
35
- )
36
- self.assertEqual(str(dg_operation), str(dg_expected))
37
-
38
29
  def test_implied_concat(self):
39
30
  if_cql = "'A' & \"B\" & 'C'"
40
31
  cc_operation = transform_cql_to_operation(if_cql)
@@ -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
@@ -37,7 +37,6 @@ FUNCTION_MAP = {
37
37
  "HasQualifier": TriccOperator.HAS_QUALIFIER,
38
38
  "DateTimeToDecimal": TriccOperator.DATETIME_TO_DECIMAL,
39
39
  "Count": TriccOperator.COUNT,
40
- "DiagnosisList": TriccOperator.DIAGNOSIS_LIST,
41
40
  }
42
41
  # TODO
43
42
  # Min
@@ -101,9 +101,9 @@ def check_and_add_concept(code_system: CodeSystem, code: str, display: str, attr
101
101
  for p in new_concept.property:
102
102
  if p.code == k:
103
103
  # TODO support other type of Codesystem Concept Property Value
104
- existing_attributes = True
104
+ existing_attributes
105
105
  if p.valueString != v:
106
- logger.warning(f"conflicting value for concept `{concept.code}` property ` {k}`: {p.valueString} != {v}")
106
+ logger.warning(f"conflicting value for 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", "concept_type"],
50
+ "attributes": ["relevance", "priority", "context_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
- "concept_type",
79
+ "context_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
- "concept_type",
97
+ "context_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
- "concept_type",
115
+ "context_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
- "concept_type",
133
+ "context_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
- "concept_type",
148
+ "context_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
- "concept_type",
163
+ "context_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
- "concept_type",
186
+ "context_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": ["concept_type"],
220
+ "attributes": ["context_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
- "concept_type",
236
+ "context_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", "data_type", "concept_type"],
298
+ "attributes": ["save", "reference", "datatype", "context_type"],
299
299
  "mandatory_attributes": ["name", "label"],
300
300
  "model": TriccNodeInput,
301
301
  },
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from tricc_oo.converters.utils import clean_name
2
+ from tricc_oo.converters.utils import clean_name, clean_str
3
3
  from tricc_oo.models.tricc import TriccNodeSelectOption, TRICC_TRUE_VALUE, TRICC_FALSE_VALUE, TriccNodeActivity
4
4
  from tricc_oo.models.calculate import TriccNodeInput
5
5
  from tricc_oo.models.base import TriccNodeBaseModel, TriccStatic, TriccReference
@@ -36,15 +36,13 @@ def get_export_name(node, replace_dots=True):
36
36
  elif isinstance(node, bool):
37
37
  return BOOLEAN_MAP[str(TRICC_TRUE_VALUE)] if node else BOOLEAN_MAP[str(TRICC_FALSE_VALUE)]
38
38
  elif isinstance(node, TriccReference):
39
- logger.warning(f"Reference {node.value} use in export, bad serialization probable")
39
+ logger.warning(f"Reference {node.value} use in export, bad serialiuation probable")
40
40
  return str(node.value)
41
41
  elif isinstance(node, (str, TriccStatic, TriccNodeSelectOption)):
42
42
  if isinstance(node, TriccNodeSelectOption):
43
43
  value = node.name
44
44
  elif isinstance(node, TriccStatic):
45
45
  value = node.value
46
- if isinstance(value, TriccNodeSelectOption):
47
- value = value.name
48
46
  else:
49
47
  value = node
50
48
  if isinstance(value, bool): # or r.value in ('true', 'false')
@@ -66,13 +64,14 @@ def get_export_name(node, replace_dots=True):
66
64
  return node
67
65
  else:
68
66
  node.gen_name()
69
- if isinstance(node, TriccNodeActivity) and getattr(node, 'instance', 1) > 1:
67
+ if isinstance(node, TriccNodeActivity) and getattr(node, 'instance', 1)>1:
70
68
  node.export_name = clean_name(
71
69
  node.name + INSTANCE_SEPARATOR + str(node.instance),
72
70
  replace_dots=replace_dots,
73
71
  )
74
72
  elif isinstance(node, TriccNodeSelectOption):
75
73
  node.export_name = node.name
74
+
76
75
  elif node.last is False:
77
76
  node.export_name = clean_name(
78
77
  node.name + VERSION_SEPARATOR + str(node.version),
@@ -7,7 +7,7 @@ import re
7
7
 
8
8
  from tricc_oo.converters.utils import remove_html, clean_str
9
9
  from tricc_oo.converters.cql_to_operation import transform_cql_to_operation
10
- from tricc_oo.converters.utils import generate_id
10
+ from tricc_oo.converters.utils import generate_id, get_rand_name
11
11
  from tricc_oo.models.base import (
12
12
  TriccOperator, TriccOperation,
13
13
  TriccStatic, TriccReference, TriccNodeType, TriccEdge, OPERATION_LIST
@@ -107,7 +107,7 @@ def create_activity(diagram, media_path, project):
107
107
  if root is not None:
108
108
  activity = TriccNodeActivity(
109
109
  root=root,
110
- name=name, # start node 'name' is saved in label
110
+ name=name, # start node 'name' is saved in label
111
111
  id=id,
112
112
  external_id=external_id,
113
113
  label=label,
@@ -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, TriccNodeInput))
131
+ issubclass(n.__class__, (TriccNodeDisplayModel, TriccNodeDisplayCalculateBase))
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", "conceptType": get_concept_type(n)},
142
+ {"datatype": "Boolean", "contextType": get_context_type(n)},
143
143
  )
144
144
  elif not isinstance(n, TriccNodeSelectNotAvailable):
145
145
  add_concept(
@@ -148,20 +148,8 @@ 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
- "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),
151
+ "datatype": get_data_type(n.tricc_type),
152
+ "contextType": get_context_type(n),
165
153
  },
166
154
  )
167
155
  if getattr(n, "save", None):
@@ -172,8 +160,8 @@ def create_activity(diagram, media_path, project):
172
160
  n.save,
173
161
  n.label,
174
162
  {
175
- "dataType": get_data_type(n.tricc_type),
176
- "conceptType": get_concept_type(n),
163
+ "datatype": get_data_type(n.tricc_type),
164
+ "contextType": get_context_type(n),
177
165
  },
178
166
  )
179
167
 
@@ -187,7 +175,7 @@ def create_activity(diagram, media_path, project):
187
175
  # link back the activity
188
176
  activity.root.activity = activity
189
177
  manage_dangling_calculate(activity)
190
- # assign the process
178
+
191
179
  if activity is not None:
192
180
  if activity.root is not None:
193
181
  project.pages[activity.id] = activity
@@ -209,7 +197,6 @@ def create_activity(diagram, media_path, project):
209
197
  )
210
198
  if images:
211
199
  project.images += images
212
- # Assign parent to NotAvailable
213
200
  for node in list(
214
201
  filter(
215
202
  lambda p_node: isinstance(p_node, TriccNodeSelectNotAvailable),
@@ -483,17 +470,17 @@ def set_additional_attributes(attribute_names, elm, node):
483
470
  # input expression can add a condition to either relevance (display) or calculate expression
484
471
  if attributename == "expression_inputs":
485
472
  attribute = [attribute]
486
- elif attributename in ["priority", "instance"]:
473
+ elif attributename == "instance":
487
474
  attribute = int(attribute)
488
475
  else:
489
476
  attribute
490
477
  setattr(node, attributename, attribute)
491
478
 
492
479
 
493
- def get_concept_type(node):
494
- concept_type = getattr(node, "concept_type", None)
495
- if concept_type:
496
- return concept_type
480
+ def get_context_type(node):
481
+ context_type = getattr(node, "context_type", None)
482
+ if context_type:
483
+ return context_type
497
484
  if isinstance(node, TriccNodeSelectMultiple):
498
485
  return "Question"
499
486
  elif isinstance(node, TriccNodeSelectOption):
@@ -548,7 +535,7 @@ def get_select_options(diagram, select_node, nodes):
548
535
  activity=select_node.activity,
549
536
  group=select_node.group,
550
537
  )
551
- set_additional_attributes(["save", "relevance", "concept_type"], elm, option)
538
+ set_additional_attributes(["save", "relevance", "context_type"], elm, option)
552
539
  load_expressions(option)
553
540
  options[i] = option
554
541
  nodes[id] = option
@@ -612,11 +599,7 @@ def inject_bridge_path(node, nodes):
612
599
  calc = TriccNodeDisplayBridge(**data)
613
600
  else:
614
601
  calc = TriccNodeBridge(**data)
615
- if node:
616
- priority = getattr(node, 'priority', None)
617
- if priority:
618
- calc.priority = priority
619
-
602
+
620
603
  for e in node.activity.edges:
621
604
  if e.target == node.id:
622
605
  if e.source in node.activity.nodes and len(node.activity.nodes[e.source].next_nodes):
@@ -636,23 +619,21 @@ def enrich_node(diagram, media_path, edge, node, activity, help_before=False):
636
619
  # get node and process type
637
620
  type, message = get_message(diagram, edge.source_external_id)
638
621
  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
622
+ if type == "help":
623
+ help = TriccNodeMoreInfo(
624
+ id=generate_id(),
625
+ name=f"{node.name}.more_info",
626
+ label=message,
627
+ parent=node,
628
+ required=None,
629
+ )
630
+ # node.help = message
631
+ if help_before:
632
+ inject_node_before(help, node, activity)
633
+ else:
634
+ set_prev_next_node(node, help, edge_only=True, activity=activity)
635
+ activity.nodes[help.id] = help
636
+ return help, None
656
637
 
657
638
  if type in (TriccNodeType.start, TriccNodeType.activity_start):
658
639
  return True
@@ -819,11 +800,9 @@ def set_mandatory_attribute(elm, mandatory_attributes, diagram=None):
819
800
  id = elm.attrib.get("id")
820
801
  attribute_value = _get_name(name, id, diagram_id)
821
802
  elif attributes == "list_name":
822
- attribute_value = elm.attrib.get("list_name", None)
823
- if not attribute_value:
824
- name = elm.attrib.get("name")
825
- id = elm.attrib.get("id")
826
- attribute_value = TRICC_LIST_NAME.format(clean_str(_get_name(name, id, diagram_id), replace_dots=True))
803
+ name = elm.attrib.get("name")
804
+ id = elm.attrib.get("id")
805
+ attribute_value = TRICC_LIST_NAME.format(clean_str(_get_name(name, id, diagram_id), replace_dots=True))
827
806
  else:
828
807
  attribute_value = elm.attrib.get(attributes)
829
808
  if attribute_value is None: