tricc-oo 1.4.12__tar.gz → 1.4.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 (52) hide show
  1. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/PKG-INFO +2 -2
  2. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/pyproject.toml +1 -1
  3. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/cql_to_operation.py +12 -22
  4. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/tricc_to_xls_form.py +1 -1
  5. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/utils.py +15 -11
  6. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/xml_to_tricc.py +2 -1
  7. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/models/base.py +205 -10
  8. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/models/calculate.py +4 -2
  9. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/models/tricc.py +0 -7
  10. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/serializers/xls_form.py +1 -1
  11. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/input/base_input_strategy.py +2 -1
  12. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/input/drawio.py +4 -18
  13. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/output/xls_form.py +17 -1
  14. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/visitors/tricc.py +236 -278
  15. tricc_oo-1.4.14/tricc_oo/visitors/utils.py +17 -0
  16. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo.egg-info/PKG-INFO +1 -1
  17. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo.egg-info/SOURCES.txt +1 -0
  18. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/LICENSE +0 -0
  19. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/README.md +0 -0
  20. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/setup.cfg +0 -0
  21. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tests/build.py +0 -0
  22. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tests/test_cql.py +0 -0
  23. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tests/to_ocl.py +0 -0
  24. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/__init__.py +0 -0
  25. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/__init__.py +0 -0
  26. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/codesystem_to_ocl.py +0 -0
  27. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/cql/cqlLexer.py +0 -0
  28. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/cql/cqlListener.py +0 -0
  29. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/cql/cqlParser.py +0 -0
  30. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/cql/cqlVisitor.py +0 -0
  31. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/datadictionnary.py +0 -0
  32. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/converters/drawio_type_map.py +0 -0
  33. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/models/__init__.py +0 -0
  34. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/models/lang.py +0 -0
  35. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/models/ocl.py +0 -0
  36. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/models/ordered_set.py +0 -0
  37. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/parsers/__init__.py +0 -0
  38. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/parsers/xml.py +0 -0
  39. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/serializers/__init__.py +0 -0
  40. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/serializers/planuml.py +0 -0
  41. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/__init__.py +0 -0
  42. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/input/__init__.py +0 -0
  43. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/output/base_output_strategy.py +0 -0
  44. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/output/spice.py +0 -0
  45. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/output/xlsform_cdss.py +0 -0
  46. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/output/xlsform_cht.py +0 -0
  47. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/strategies/output/xlsform_cht_hf.py +0 -0
  48. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/visitors/__init__.py +0 -0
  49. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo/visitors/xform_pd.py +0 -0
  50. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo.egg-info/dependency_links.txt +0 -0
  51. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo.egg-info/requires.txt +0 -0
  52. {tricc_oo-1.4.12 → tricc_oo-1.4.14}/tricc_oo.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: tricc-oo
3
- Version: 1.4.12
3
+ Version: 1.4.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.4.12"
7
+ version = "1.4.14"
8
8
  description = "Python library that converts CDSS L2 in L3"
9
9
  readme = "README.md"
10
10
  license-files = ["LICENSE"]
@@ -3,7 +3,7 @@ from tricc_oo.converters.cql.cqlLexer import cqlLexer
3
3
  from tricc_oo.converters.cql.cqlParser import cqlParser
4
4
  from tricc_oo.converters.cql.cqlVisitor import cqlVisitor
5
5
  from tricc_oo.converters.utils import clean_name
6
- from tricc_oo.models.base import TriccOperator, TriccOperation, TriccStatic, TriccReference
6
+ from tricc_oo.models.base import TriccOperator, TriccOperation, TriccStatic, TriccReference, not_clean, or_join, and_join
7
7
  import logging
8
8
 
9
9
  logger = logging.getLogger("default")
@@ -148,7 +148,7 @@ class cqlToXlsFormVisitor(cqlVisitor):
148
148
 
149
149
  def visitNegateMembershipExpression(self, ctx):
150
150
  function_name = ctx.getChild(2).getText()
151
- return TriccOperation(TriccOperator.NOT,[self._get_membership_expression(ctx, function_name)])
151
+ return not_clean(self._get_membership_expression(ctx, function_name))
152
152
 
153
153
 
154
154
  def visitBetweenExpression(self, ctx):
@@ -174,10 +174,7 @@ class cqlToXlsFormVisitor(cqlVisitor):
174
174
  if params[0] == 'not':
175
175
  if isinstance(op, TriccStatic) and isinstance(op.value, str):
176
176
  logger.warning(f"not operator on a string {op.value}")
177
- op = TriccOperation(
178
- operator = TriccOperator.NOT,
179
- reference = [op]
180
- )
177
+ op = not_clean(op)
181
178
 
182
179
  return op
183
180
 
@@ -200,23 +197,16 @@ class cqlToXlsFormVisitor(cqlVisitor):
200
197
  elif hasattr(ctx, 'expressionTerm'):
201
198
  left = self.visit(ctx.expressionTerm(0))
202
199
  right = self.visit(ctx.expressionTerm(1))
203
- if isinstance(left, TriccOperation) and left.operator == operator and operator in (TriccOperator.OR, TriccOperator.AND):
204
- left.append(right)
205
- return left
206
- if isinstance(right, TriccOperation) and right.operator == operator and operator in (TriccOperator.OR, TriccOperator.AND):
207
- left.append(left)
208
- return right
209
- op = TriccOperation(operator)
210
- op.reference = [left, right]
211
- return op
200
+ if operator == TriccOperator.AND:
201
+ return and_join([left, right])
202
+ elif operator == TriccOperator.OR:
203
+ return or_join([left, right])
204
+ else:
205
+ op = TriccOperation(operator, [left, right])
206
+ return op
212
207
 
213
208
  def visitNotExpression(self, ctx):
214
- expr = self.visit(ctx.expression())
215
- op = TriccOperation(TriccOperator.NOT)
216
- if isinstance(expr, TriccStatic) and isinstance(expr.value, str):
217
- logger.warning(f"not operator on a string {expr.value}")
218
- op.reference = [expr]
219
- return op
209
+ return not_clean(self.visit(ctx.expression()))
220
210
 
221
211
  def visitIsTrueOrFalseExpression(self, ctx):
222
212
  expr = self.visit(ctx.expression())
@@ -245,7 +235,7 @@ class cqlToXlsFormVisitor(cqlVisitor):
245
235
  '>': TriccOperator.MORE,
246
236
  '>=': TriccOperator.MORE_OR_EQUAL,
247
237
  '=': TriccOperator.EQUAL,
248
- '!=': TriccOperator.NOT_EQUAL
238
+ '!=': TriccOperator.NOTEQUAL
249
239
  }
250
240
  op = TriccOperation(op_map[op_text])
251
241
  op.reference = [left, right]
@@ -3,7 +3,7 @@ import re
3
3
 
4
4
  from tricc_oo.converters.utils import clean_str,clean_name
5
5
  from tricc_oo.models import *
6
- from tricc_oo.visitors.tricc import clean_list_or, negate_term
6
+ from tricc_oo.visitors.tricc import clean_or_list, negate_term
7
7
 
8
8
  # from babel import _
9
9
 
@@ -4,8 +4,9 @@ import random
4
4
  import string
5
5
  import hashlib
6
6
  from markdownify import markdownify as md
7
-
8
-
7
+ import warnings
8
+ from bs4 import MarkupResemblesLocatorWarning
9
+ warnings.filterwarnings("ignore", category=MarkupResemblesLocatorWarning)
9
10
  logger = logging.getLogger("default")
10
11
 
11
12
 
@@ -49,13 +50,16 @@ def get_rand_name(name=None, length=8):
49
50
 
50
51
  # the soup.text strips off the html formatting also
51
52
  def remove_html(string):
52
- text = md(
53
- string,
54
- strip=["img", "table", "a"],
55
- strong_em_symbol="*",
56
- escape_underscores=False,
57
- escape_asterisks=False,
58
- bullets=["-", "*"],
59
- )
53
+
54
+ if ' ' in string:
55
+ text = md(
56
+ string,
57
+ strip=["img", "table", "a"],
58
+ strong_em_symbol="*",
59
+ escape_underscores=False,
60
+ escape_asterisks=False,
61
+ bullets=["-", "*"],
62
+ )
60
63
 
61
- return text
64
+ return text
65
+ return string
@@ -118,6 +118,7 @@ def create_activity(diagram, media_path, project):
118
118
  activity.root.process == "main" or activity.root.process is None
119
119
  ):
120
120
  project.start_pages["main"] = activity
121
+ activity.root.process = 'main'
121
122
  elif activity.root.process is not None:
122
123
  if activity.root.process not in project.start_pages:
123
124
  project.start_pages[activity.root.process] = []
@@ -373,7 +374,7 @@ def create_root_node(diagram):
373
374
  label=elm.attrib.get("label"),
374
375
  form_id=elm.attrib.get("form_id"),
375
376
  relevance=elm.attrib.get("relevance"),
376
- process=elm.attrib.get("process") or 'main',
377
+ process=elm.attrib.get('process', 'main'),
377
378
  )
378
379
  else:
379
380
  elm = get_tricc_type(diagram, "object", TriccNodeType.activity_start)
@@ -113,13 +113,25 @@ class TriccBaseModel(BaseModel):
113
113
  def get_datatype(self):
114
114
  return self.datatype or self.tricc_type
115
115
 
116
+ def to_dict(self):
117
+ return {key: value for key, value in vars(self).items() if not key.startswith('_')}
118
+
116
119
  def make_instance(self, nb_instance, **kwargs):
117
120
  instance = self.copy()
118
121
  # change the id to avoid collision of name
119
122
  instance.id = generate_id(f"{self.id}{nb_instance}")
120
123
  instance.instance = int(nb_instance)
121
124
  instance.base_instance = self
122
-
125
+ attr_dict = self.to_dict()
126
+ for attr, value in attr_dict.items():
127
+ if not attr.startswith('_') and value is not None:
128
+ try:
129
+ if hasattr(value, 'copy'):
130
+ setattr(instance, attr, value.copy())
131
+ else:
132
+ setattr(instance, attr, value)
133
+ except Exception as e:
134
+ logger.warning(f"Warning: Could not copy attribute {attr}: {e}")
123
135
  # assign the defualt group
124
136
  # if activity is not None and self.group == activity.base_instance:
125
137
  # instance.group = instance
@@ -161,12 +173,6 @@ class TriccEdge(TriccBaseModel):
161
173
  target_external_id: triccId = None
162
174
  value: Optional[str] = None
163
175
 
164
- def make_instance(self, instance_nb, activity=None):
165
- instance = super().make_instance(instance_nb, activity=activity)
166
- #if issubclass(self.source.__class__, TriccBaseModel):
167
- instance.source = self.source if isinstance(self.source, str) else self.source.copy()
168
- #if issubclass(self.target.__class__, TriccBaseModel):
169
- return instance
170
176
 
171
177
 
172
178
  class TriccGroup(TriccBaseModel):
@@ -319,16 +325,19 @@ class TriccOperator(StrEnum):
319
325
  OR = 'or' # or between left and rights
320
326
  NATIVE = 'native' #default left is native expression
321
327
  ISTRUE = 'istrue' # left is right
328
+ ISNOTTRUE = 'isnottrue'
322
329
  ISFALSE = 'isfalse' # left is false
330
+ ISNOTFALSE = 'isnotfalse' # left is false
323
331
  SELECTED = 'selected' # right must be la select and one or several options
324
332
  MORE_OR_EQUAL = 'more_or_equal'
325
333
  LESS_OR_EQUAL = 'less_or_equal'
326
334
  EQUAL = 'equal'
327
335
  MORE = 'more'
328
- NOT_EQUAL = 'not_equal'
336
+ NOTEQUAL = 'not_equal'
329
337
  BETWEEN = 'between'
330
338
  LESS = 'less'
331
339
  CONTAINS = 'contains' # ref, txt Does CONTAINS make sense, like Select with wildcard
340
+ NOTEXISTS = 'notexists'
332
341
  EXISTS = 'exists'
333
342
  NOT = 'not'
334
343
  ISNULL = 'isnull'
@@ -367,13 +376,16 @@ RETURNS_BOOLEAN =[
367
376
  TriccOperator.BETWEEN,
368
377
  TriccOperator.CONTAINS,
369
378
  TriccOperator.EXISTS,
379
+ TriccOperator.NOTEXISTS,
370
380
  TriccOperator.ISFALSE,
381
+ TriccOperator.ISNOTFALSE,
371
382
  TriccOperator.ISNOTNULL,
372
383
  TriccOperator.ISTRUE,
384
+ TriccOperator.ISNOTTRUE,
373
385
  TriccOperator.SELECTED,
374
386
  TriccOperator.HAS_QUALIFIER,
375
387
  TriccOperator.NOT,
376
- TriccOperator.NOT_EQUAL,
388
+ TriccOperator.NOTEQUAL,
377
389
  TriccOperator.MORE_OR_EQUAL,
378
390
  TriccOperator.LESS_OR_EQUAL,
379
391
  TriccOperator.EQUAL,
@@ -405,7 +417,7 @@ OPERATION_LIST = {
405
417
  '>=': TriccOperator.MORE_OR_EQUAL,
406
418
  '<=': TriccOperator.LESS_OR_EQUAL,
407
419
  '==': TriccOperator.EQUAL,
408
- '!=': TriccOperator.NOT_EQUAL,
420
+ '!=': TriccOperator.NOTEQUAL,
409
421
  '=': TriccOperator.EQUAL,
410
422
  '>': TriccOperator.MORE,
411
423
  '<': TriccOperator.LESS
@@ -425,6 +437,9 @@ class TriccOperation(BaseModel):
425
437
  str_ref = map(str, self.reference)
426
438
  return f"{self.operator}({', '.join(map(str, str_ref))})"
427
439
 
440
+ def __hash__(self):
441
+ return hash(self.__repr__())
442
+
428
443
  def __repr__(self):
429
444
  return "TriccOperation:"+self.__str__()
430
445
 
@@ -532,6 +547,186 @@ class TriccOperation(BaseModel):
532
547
  def copy(self, keep_node=False):
533
548
  return self.__copy__(keep_node)
534
549
 
550
+ # function that make multipat and
551
+ # @param argv list of expression to join with and
552
+ def clean_and_list(argv):
553
+ for a in list(argv):
554
+ if isinstance(a, TriccOperation) and a.operator == TriccOperator.AND:
555
+ argv.remove(a)
556
+ return clean_and_list([*argv,*a.reference])
557
+ elif a == TriccStatic(True) or a == True:
558
+ argv.remove(a)
559
+ elif a == TriccStatic(False) :
560
+ return [TriccStatic(False)]
561
+
562
+ internal = list(set(argv))
563
+ for a in internal:
564
+ for b in internal[internal.index(a)+1:]:
565
+ if not_clean(b) == a:
566
+ return [TriccStatic(False)]
567
+ return sorted(list(set(argv)), key=str)
568
+
569
+ def not_clean(a):
570
+ new_operator = None
571
+ if a is None or isinstance(a, str) and a == '':
572
+ return TriccStatic(False)
573
+ elif isinstance(a, TriccStatic) and a == TriccStatic(False):
574
+ return TriccStatic(True)
575
+ elif isinstance(a, TriccStatic) and a == TriccStatic(True):
576
+ return TriccStatic(False)
577
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.ISTRUE:
578
+ new_operator = TriccOperator.ISNOTTRUE
579
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.ISNOTTRUE:
580
+ new_operator = TriccOperator.ISTRUE
581
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.ISFALSE:
582
+ new_operator = TriccOperator.ISNOTFALSE
583
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.ISNOTFALSE:
584
+ new_operator = TriccOperator.ISFALSE
585
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.ISNULL:
586
+ new_operator = TriccOperator.ISNOTNULL
587
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.ISNOTNULL:
588
+ new_operator = TriccOperator.ISNULL
589
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.LESS:
590
+ new_operator = TriccOperator.MORE_OR_EQUAL
591
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.MORE:
592
+ new_operator = TriccOperator.LESS_OR_EQUAL
593
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.LESS_OR_EQUAL:
594
+ new_operator = TriccOperator.MORE
595
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.MORE_OR_EQUAL:
596
+ new_operator = TriccOperator.LESS
597
+ elif isinstance(a, TriccOperation) and a.operator == TriccOperator.NOT:
598
+ return a.reference[0]
599
+
600
+ if new_operator:
601
+ return TriccOperation(
602
+ new_operator,
603
+ a.reference
604
+ )
605
+
606
+ elif not isinstance(a, TriccOperation) and issubclass(a.__class__, object):
607
+ return TriccOperation(
608
+ operator=TriccOperator.NOTEXISTS,
609
+ reference=[a]
610
+ )
611
+ else:
612
+ return TriccOperation(
613
+ TriccOperator.NOT,
614
+ [a]
615
+ )
616
+
617
+
618
+
619
+ # function that generate remove unsure condition
620
+ # @param list_or
621
+ # @param and elm use upstream
622
+ def clean_or_list(list_or, elm_and=None):
623
+ for a in list(list_or):
624
+ if isinstance(a, TriccOperation) and a.operator == TriccOperator.OR:
625
+ list_or.remove(a)
626
+ return clean_or_list([*list_or,*a.reference])
627
+ elif a == TriccStatic(False) or a == False or a == 0:
628
+ list_or.remove(a)
629
+ elif a == TriccStatic(True) or a == True or a == 1 or (elm_and is not None and not_clean(a) in list_or):
630
+ return [TriccStatic(True)]
631
+ # if there is x and not(X) in an OR list them the list is always true
632
+ elif elm_and is not None and (not_clean(a) == elm_and or a == elm_and ):
633
+ list_or.remove(a)
634
+ internal = list(list_or)
635
+ for a in internal:
636
+ for b in internal[internal.index(a)+1:]:
637
+ if not_clean(b) == a:
638
+ return [TriccStatic(True)]
639
+ if len(list_or) == 0:
640
+ return []
641
+
642
+ return sorted(list(set(list_or)), key=str)
643
+
644
+ def and_join(argv):
645
+ argv=clean_and_list(argv)
646
+ if len(argv) == 0:
647
+ return ''
648
+ elif len(argv) == 1:
649
+ return argv[0]
650
+ else:
651
+ return TriccOperation(
652
+ TriccOperator.AND,
653
+ argv
654
+ )
655
+
656
+ # function that make a 2 part and
657
+ # @param left part
658
+ # @param right part
659
+ def simple_and_join(left, right):
660
+ expression = None
661
+ # no term is considered as True
662
+ left_issue = left is None or left == ''
663
+ right_issue = right is None or right == ''
664
+ left_neg = not_clean(left)
665
+ right_neg = not_clean(right)
666
+ if left_issue and right_issue:
667
+ logger.critical("and with both terms empty")
668
+ elif left_neg == right or right_neg == left:
669
+ return TriccStatic(False)
670
+ elif left_issue:
671
+ logger.debug('and with empty left term')
672
+ return right
673
+ elif left == '1' or left == 1 or left == TriccStatic(True) or left is True:
674
+ return right
675
+ elif right_issue:
676
+ logger.debug('and with empty right term')
677
+ return left
678
+ elif right == '1' or right == 1 or right == TriccStatic(True) or right is True:
679
+ return left
680
+ else:
681
+ return TriccOperation(
682
+ TriccOperator.AND,
683
+ [left, right]
684
+ )
685
+
686
+ def or_join(list_or, elm_and=None):
687
+ cleaned_list = clean_or_list(list_or, elm_and)
688
+ if len(cleaned_list) == 1:
689
+ return cleaned_list[0]
690
+ elif len(cleaned_list)>1:
691
+ return TriccOperation(
692
+ TriccOperator.OR,
693
+ cleaned_list
694
+ )
695
+ else:
696
+ logger.error("empty or list")
697
+
698
+
699
+
700
+ # function that make a 2 part NAND
701
+ # @param left part
702
+ # @param right part
703
+ def nand_join(left, right):
704
+ # no term is considered as True
705
+ left_issue = left is None or left == ''
706
+ right_issue = right is None or right == ''
707
+ left_neg = left == False or left == 0 or left == '0' or left == TriccStatic(False)
708
+ 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
+ if left_issue and right_issue:
714
+ logger.critical("and with both terms empty")
715
+ elif left_issue:
716
+ logger.debug('and with empty left term')
717
+ return negate_term(right)
718
+ elif left == '1' or left == 1 or left == TriccStatic(True):
719
+ return negate_term(right)
720
+ elif right_issue :
721
+ logger.debug('and with empty right term')
722
+ return TriccStatic(False)
723
+ elif right == '1' or right == 1 or left_neg or right == TriccStatic(True):
724
+ return TriccStatic(False)
725
+ elif right_neg:
726
+ return left
727
+ else:
728
+ return and_join([left, negate_term(right)])
729
+
535
730
 
536
731
  TriccGroup.update_forward_refs()
537
732
  TriccEdge.update_forward_refs()
@@ -182,7 +182,7 @@ class TriccNodeEnd(TriccNodeDisplayCalculateBase):
182
182
  process: str = None
183
183
  def __init__(self, **data):
184
184
  if data.get('name', None) is None:
185
- data['name'] = 'tricc_end_'
185
+ data['name'] = 'tricc_end_' + data.get('process', '')
186
186
  super().__init__(**data)
187
187
  # FOR END
188
188
 
@@ -190,9 +190,11 @@ class TriccNodeEnd(TriccNodeDisplayCalculateBase):
190
190
 
191
191
  def set_name(self):
192
192
  if self.name is None:
193
- self.name = 'tricc_end'
193
+ self.name = self.get_reference()
194
194
  #self.name = END_NODE_FORMAT.format(self.activity.id)
195
195
 
196
+ def get_reference(self):
197
+ return 'tricc_end_' + (self.process or '')
196
198
 
197
199
  class TriccNodeActivityStart(TriccNodeFakeCalculateBase):
198
200
  tricc_type: TriccNodeType = TriccNodeType.activity_start
@@ -32,8 +32,6 @@ class TriccNodeCalculateBase(TriccNodeBaseModel):
32
32
  instance.reference = [e.copy() if isinstance(e, (TriccReference, TriccOperation)) else (TriccReference(e.name) if hasattr(e, 'name') else e) for e in self.reference]
33
33
  else:
34
34
  instance.reference = None
35
- if self.expression_reference:
36
- instance.expression_reference = self.expression_reference.copy()
37
35
  version = self.version + 1
38
36
  instance.version = version
39
37
  return instance
@@ -237,11 +235,6 @@ class TriccNodeDisplayModel(TriccNodeBaseModel):
237
235
  group: Optional[Union[TriccGroup, TriccNodeActivity]] = None
238
236
  relevance: Optional[Union[Expression, TriccOperation]] = None
239
237
 
240
- def make_instance(self, instance_nb, activity=None):
241
- instance = super().make_instance(instance_nb, activity=activity)
242
- instance.relevance = self.relevance.copy() if self.relevance else None
243
-
244
- return instance
245
238
 
246
239
  # to use the enum value of the TriccNodeType
247
240
 
@@ -59,7 +59,7 @@ def start_group(
59
59
  relevance_expression
60
60
  )
61
61
  elif isinstance(relevance_expression, TriccStatic):
62
- relevance_expression = str(relevance.value)
62
+ relevance_expression = str(relevance_expression.value)
63
63
 
64
64
  # elif is_activity:
65
65
  # relevance_expression = TRICC_CALC_EXPRESSION.format(get_export_name(cur_group.root))
@@ -55,7 +55,8 @@ class BaseInputStrategy:
55
55
  root = TriccNodeMainStart(
56
56
  id=generate_id('s-determine-diagnosis'),
57
57
  form_id=root_process.form_id,
58
- label=root_process.label
58
+ label=root_process.label,
59
+ process='main'
59
60
  )
60
61
  nodes = {}
61
62
  nodes[root.id] = root
@@ -11,6 +11,7 @@ from tricc_oo.visitors.tricc import (
11
11
  stashed_node_func,
12
12
  TriccProject
13
13
  )
14
+ from tricc_oo.visitors.utils import PROCESSES
14
15
  from tricc_oo.converters.codesystem_to_ocl import transform_fhir_to_ocl
15
16
 
16
17
  from tricc_oo.models import *
@@ -22,23 +23,7 @@ logger = logging.getLogger("default")
22
23
 
23
24
  class DrawioStrategy(BaseInputStrategy):
24
25
 
25
- processes = [
26
- "triage",
27
- "registration",
28
- "emergency-care",
29
- "local-urgent-care",
30
- "actue-tertiary-care",
31
- "history-and-physical",
32
- "diagnostic-testing",
33
- "determine-diagnosis",
34
- "provide-counseling",
35
- "dispense-medications",
36
- "monitor-and-follow-up-of-patient",
37
- "alerts-reminders-education",
38
- "discharge-referral-of-patient",
39
- "charge-for-service",
40
- "record-and-report",
41
- ]
26
+ processes = PROCESSES
42
27
 
43
28
  def process_pages(self, start_page, project):
44
29
  # create the graph
@@ -57,7 +42,8 @@ class DrawioStrategy(BaseInputStrategy):
57
42
  used_calculates=used_calculates,
58
43
  calculates=calculates,
59
44
  recursive=False,
60
- codesystems=project.code_systems
45
+ codesystems=project.code_systems,
46
+ process=[start_page.root.process]
61
47
  )
62
48
 
63
49
  logger.info("# check if all edges (arrow) where used")
@@ -450,6 +450,22 @@ class XLSFormStrategy(BaseOutPutStrategy):
450
450
  return f"{ref_expressions[0]}=''"
451
451
  def tricc_operation_isnotnull(self, ref_expressions):
452
452
  return f"{ref_expressions[0]}!=''"
453
+
454
+ def tricc_operation_isnottrue(self, ref_expressions):
455
+ if str(BOOLEAN_MAP[str(TRICC_TRUE_VALUE)]).isnumeric():
456
+ return f"{ref_expressions[0]}<{BOOLEAN_MAP[str(TRICC_TRUE_VALUE)]}"
457
+ else:
458
+ return f"{ref_expressions[0]}!={BOOLEAN_MAP[str(TRICC_TRUE_VALUE)]}"
459
+ def tricc_operation_isnotfalse(self, ref_expressions):
460
+ if str(BOOLEAN_MAP[str(TRICC_FALSE_VALUE)]).isnumeric():
461
+ return f"{ref_expressions[0]}>{BOOLEAN_MAP[str(TRICC_FALSE_VALUE)]}"
462
+ else:
463
+ return f"{ref_expressions[0]}!={BOOLEAN_MAP[str(TRICC_FALSE_VALUE)]}"
464
+ def tricc_operation_notexist(self, ref_expressions):
465
+ return f"{ref_expressions[0]}=''"
466
+
467
+
468
+
453
469
  def tricc_operation_case(self, ref_expressions):
454
470
  ifs = 0
455
471
  parts = []
@@ -581,7 +597,7 @@ class XLSFormStrategy(BaseOutPutStrategy):
581
597
  if kwargs.get('warn', True):
582
598
  logger.debug("generation of calculate for node {}".format(node.get_name()))
583
599
  if hasattr(node, 'expression') and (node.expression is None) and issubclass(node.__class__,TriccNodeCalculateBase):
584
- node.expression = get_node_expressions(node, processed_nodes)
600
+ node.expression = get_node_expressions(node, processed_nodes, process=kwargs.get('process', 'main '))
585
601
  # continue walk
586
602
  return True
587
603
  return False