cqm-parsers 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +29 -0
  3. data/README.md +21 -0
  4. data/Rakefile +19 -0
  5. data/lib/ext/code.rb +10 -0
  6. data/lib/ext/data_element.rb +24 -0
  7. data/lib/hqmf-model/attribute.rb +63 -0
  8. data/lib/hqmf-model/data_criteria.rb +467 -0
  9. data/lib/hqmf-model/document.rb +253 -0
  10. data/lib/hqmf-model/population_criteria.rb +102 -0
  11. data/lib/hqmf-model/precondition.rb +94 -0
  12. data/lib/hqmf-model/types.rb +457 -0
  13. data/lib/hqmf-model/utilities.rb +52 -0
  14. data/lib/hqmf-parser.rb +116 -0
  15. data/lib/hqmf-parser/1.0/attribute.rb +121 -0
  16. data/lib/hqmf-parser/1.0/comparison.rb +34 -0
  17. data/lib/hqmf-parser/1.0/data_criteria.rb +92 -0
  18. data/lib/hqmf-parser/1.0/document.rb +195 -0
  19. data/lib/hqmf-parser/1.0/expression.rb +60 -0
  20. data/lib/hqmf-parser/1.0/observation.rb +61 -0
  21. data/lib/hqmf-parser/1.0/population_criteria.rb +75 -0
  22. data/lib/hqmf-parser/1.0/precondition.rb +90 -0
  23. data/lib/hqmf-parser/1.0/range.rb +76 -0
  24. data/lib/hqmf-parser/1.0/restriction.rb +162 -0
  25. data/lib/hqmf-parser/1.0/utilities.rb +55 -0
  26. data/lib/hqmf-parser/2.0/data_criteria.rb +372 -0
  27. data/lib/hqmf-parser/2.0/data_criteria_helpers/dc_base_extract.rb +80 -0
  28. data/lib/hqmf-parser/2.0/data_criteria_helpers/dc_definition_from_template_or_type_extract.rb +201 -0
  29. data/lib/hqmf-parser/2.0/data_criteria_helpers/dc_post_processing.rb +85 -0
  30. data/lib/hqmf-parser/2.0/data_criteria_helpers/dc_specific_occurrences_and_source_data_criteria_extract.rb +117 -0
  31. data/lib/hqmf-parser/2.0/document.rb +304 -0
  32. data/lib/hqmf-parser/2.0/document_helpers/doc_population_helper.rb +173 -0
  33. data/lib/hqmf-parser/2.0/document_helpers/doc_utilities.rb +131 -0
  34. data/lib/hqmf-parser/2.0/field_value_helper.rb +251 -0
  35. data/lib/hqmf-parser/2.0/population_criteria.rb +134 -0
  36. data/lib/hqmf-parser/2.0/precondition.rb +73 -0
  37. data/lib/hqmf-parser/2.0/source_data_criteria_helper.rb +112 -0
  38. data/lib/hqmf-parser/2.0/types.rb +448 -0
  39. data/lib/hqmf-parser/2.0/utilities.rb +45 -0
  40. data/lib/hqmf-parser/2.0/value_set_helper.rb +104 -0
  41. data/lib/hqmf-parser/converter/pass1/data_criteria_converter.rb +257 -0
  42. data/lib/hqmf-parser/converter/pass1/document_converter.rb +133 -0
  43. data/lib/hqmf-parser/converter/pass1/population_criteria_converter.rb +185 -0
  44. data/lib/hqmf-parser/converter/pass1/precondition_converter.rb +173 -0
  45. data/lib/hqmf-parser/converter/pass1/precondition_extractor.rb +201 -0
  46. data/lib/hqmf-parser/converter/pass1/simple_data_criteria.rb +26 -0
  47. data/lib/hqmf-parser/converter/pass1/simple_operator.rb +89 -0
  48. data/lib/hqmf-parser/converter/pass1/simple_population_criteria.rb +10 -0
  49. data/lib/hqmf-parser/converter/pass1/simple_precondition.rb +51 -0
  50. data/lib/hqmf-parser/converter/pass1/simple_restriction.rb +64 -0
  51. data/lib/hqmf-parser/converter/pass2/comparison_converter.rb +112 -0
  52. data/lib/hqmf-parser/converter/pass2/operator_converter.rb +102 -0
  53. data/lib/hqmf-parser/cql/data_criteria.rb +57 -0
  54. data/lib/hqmf-parser/cql/data_criteria_helpers/dc_definition_from_template_or_type_extract.rb +79 -0
  55. data/lib/hqmf-parser/cql/data_criteria_helpers/dc_post_processing.rb +43 -0
  56. data/lib/hqmf-parser/cql/document.rb +78 -0
  57. data/lib/hqmf-parser/cql/document_helpers/doc_population_helper.rb +124 -0
  58. data/lib/hqmf-parser/cql/value_set_helper.rb +103 -0
  59. data/lib/hqmf-parser/parser.rb +100 -0
  60. data/lib/qrda-export/catI-r5/qrda1_r5.rb +125 -0
  61. data/lib/qrda-export/helper/cat_1_view_helper.rb +142 -0
  62. data/lib/qrda-export/helper/code_system_helper.rb +77 -0
  63. data/lib/qrda-export/helper/date_helper.rb +81 -0
  64. data/lib/qrda-import/base-importers/demographics_importer.rb +47 -0
  65. data/lib/qrda-import/base-importers/medication_importer.rb +22 -0
  66. data/lib/qrda-import/base-importers/section_importer.rb +196 -0
  67. data/lib/qrda-import/cda_identifier.rb +19 -0
  68. data/lib/qrda-import/data-element-importers/adverse_event_importer.rb +23 -0
  69. data/lib/qrda-import/data-element-importers/allergy_intolerance_importer.rb +21 -0
  70. data/lib/qrda-import/data-element-importers/assessment_performed_importer.rb +23 -0
  71. data/lib/qrda-import/data-element-importers/communication_from_patient_to_provider_importer.rb +18 -0
  72. data/lib/qrda-import/data-element-importers/communication_from_provider_to_patient_importer.rb +18 -0
  73. data/lib/qrda-import/data-element-importers/communication_from_provider_to_provider_importer.rb +20 -0
  74. data/lib/qrda-import/data-element-importers/device_applied_importer.rb +23 -0
  75. data/lib/qrda-import/data-element-importers/device_order_importer.rb +18 -0
  76. data/lib/qrda-import/data-element-importers/diagnosis_importer.rb +23 -0
  77. data/lib/qrda-import/data-element-importers/diagnostic_study_order_importer.rb +20 -0
  78. data/lib/qrda-import/data-element-importers/diagnostic_study_performed_importer.rb +30 -0
  79. data/lib/qrda-import/data-element-importers/encounter_order_importer.rb +20 -0
  80. data/lib/qrda-import/data-element-importers/encounter_performed_importer.rb +41 -0
  81. data/lib/qrda-import/data-element-importers/immunization_administered_importer.rb +18 -0
  82. data/lib/qrda-import/data-element-importers/intervention_order_importer.rb +18 -0
  83. data/lib/qrda-import/data-element-importers/intervention_performed_importer.rb +22 -0
  84. data/lib/qrda-import/data-element-importers/laboratory_test_order_importer.rb +20 -0
  85. data/lib/qrda-import/data-element-importers/laboratory_test_performed_importer.rb +28 -0
  86. data/lib/qrda-import/data-element-importers/medication_active_importer.rb +17 -0
  87. data/lib/qrda-import/data-element-importers/medication_administered_importer.rb +17 -0
  88. data/lib/qrda-import/data-element-importers/medication_discharge_importer.rb +19 -0
  89. data/lib/qrda-import/data-element-importers/medication_dispensed_importer.rb +19 -0
  90. data/lib/qrda-import/data-element-importers/medication_order_importer.rb +16 -0
  91. data/lib/qrda-import/data-element-importers/patient_characteristic_expired.rb +21 -0
  92. data/lib/qrda-import/data-element-importers/physical_exam_performed_importer.rb +26 -0
  93. data/lib/qrda-import/data-element-importers/procedure_order_importer.rb +26 -0
  94. data/lib/qrda-import/data-element-importers/procedure_performed_importer.rb +34 -0
  95. data/lib/qrda-import/data-element-importers/substance_administered_importer.rb +16 -0
  96. data/lib/qrda-import/entry_finder.rb +20 -0
  97. data/lib/qrda-import/entry_package.rb +16 -0
  98. data/lib/qrda-import/narrative_reference_handler.rb +33 -0
  99. data/lib/qrda-import/patient_importer.rb +105 -0
  100. data/lib/util/code_system_helper.rb +76 -0
  101. data/lib/util/counter.rb +20 -0
  102. data/lib/util/hqmf_template_helper.rb +39 -0
  103. metadata +340 -0
@@ -0,0 +1,60 @@
1
+ module HQMF1
2
+
3
+ class Expression
4
+
5
+ include HQMF1::Utilities
6
+
7
+ attr_reader :text, :value, :type
8
+
9
+ def initialize(entry)
10
+ @entry = entry
11
+ @text = @entry.xpath('./*/cda:derivationExpr').text.strip
12
+ type = attr_val('./*/cda:value/@xsi:type')
13
+ case type
14
+ when 'IVL_PQ'
15
+ @value = Range.new(@entry.xpath('./*/cda:value'))
16
+ when 'PQ'
17
+ @value = Value.new(@entry.xpath('./*/cda:value'))
18
+ when 'ANYNonNull'
19
+ @value = HQMF::AnyValue.new
20
+ when nil
21
+ @value = HQMF::AnyValue.new
22
+ else
23
+ raise "Unknown expression value type #{type}"
24
+ end
25
+ @type = match_type
26
+ end
27
+
28
+ def match_type
29
+ case @text
30
+ when /^COUNT(.*)$/
31
+ "COUNT"
32
+ when /^MIN(.*)$/
33
+ "MIN"
34
+ when /^MAX(.*)$/
35
+ "MAX"
36
+ when /^DATEDIFF(.*)$/
37
+ "DATEDIFF"
38
+ when /^TIMEDIFF(.*)$/
39
+ "TIMEDIFF"
40
+ when /^MEDIAN(.*)$/
41
+ "MEDIAN"
42
+ when /^AVG(.*)$/
43
+ "MEAN"
44
+ else
45
+ raise "unknown expression type: #{@text}"
46
+ end
47
+ end
48
+
49
+ def to_json
50
+
51
+ json = build_hash(self, [:text,:type])
52
+ json[:value] = self.value.to_json if self.value
53
+ json
54
+
55
+ end
56
+
57
+ end
58
+
59
+
60
+ end
@@ -0,0 +1,61 @@
1
+ module HQMF1
2
+ # Represents an HQMF population criteria
3
+ class Observation
4
+
5
+ include HQMF1::Utilities
6
+
7
+ attr_reader :preconditions, :entry, :doc
8
+ attr_accessor :id, :hqmf_id, :stratification_id
9
+
10
+ # Create a new population criteria from the supplied HQMF entry
11
+ # @param [Nokogiri::XML::Element] the HQMF entry
12
+ def initialize(entry, doc)
13
+ @doc = doc
14
+ @entry = entry
15
+ @id = attr_val('cda:observation/cda:id/@root').upcase
16
+ @preconditions = [Precondition.new(@entry, nil, @doc)]
17
+ end
18
+
19
+ # Get the code for the population criteria
20
+ # @return [String] the code (e.g. IPP, DEMON, NUMER, DENEX, DENEXCEP)
21
+ def code
22
+ HQMF::PopulationCriteria::OBSERV
23
+ end
24
+
25
+ # Get the id for the population criteria, used elsewhere in the HQMF document to
26
+ # refer to this criteria
27
+ # @return [String] the id
28
+ def id
29
+ @id
30
+ end
31
+
32
+ def title
33
+ "Measure Observation"
34
+ end
35
+
36
+ def reference
37
+ nil
38
+ end
39
+
40
+ def to_json
41
+
42
+ json = {}
43
+ self.preconditions.compact.each do |precondition|
44
+ json[:preconditions] ||= []
45
+ json[:preconditions] << precondition.to_json
46
+ end
47
+ json[:preconditions].each {|p| p[:conjunction] ||= "AND"}
48
+
49
+ json[:id] = id
50
+ json[:title] = title
51
+ json[:code] = code
52
+ json[:hqmf_id] = hqmf_id if hqmf_id
53
+ json[:stratification_id] = stratification_id if stratification_id
54
+ json[:reference] = reference
55
+
56
+ {self.code => json}
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,75 @@
1
+ module HQMF1
2
+ # Represents an HQMF population criteria
3
+ class PopulationCriteria
4
+
5
+ include HQMF1::Utilities
6
+
7
+ attr_reader :preconditions, :entry, :doc
8
+ attr_accessor :id, :hqmf_id, :stratification_id
9
+
10
+ # Create a new population criteria from the supplied HQMF entry
11
+ # @param [Nokogiri::XML::Element] the HQMF entry
12
+ def initialize(entry, doc)
13
+ @doc = doc
14
+ @entry = entry
15
+ @id = attr_val('cda:observation/cda:id/@root').upcase
16
+ @preconditions = @entry.xpath('./*/cda:sourceOf[@typeCode="PRCN"]').collect do |entry|
17
+ pc = Precondition.new(entry, nil, @doc)
18
+ if pc.preconditions.length==0 && !pc.comparison && pc.restrictions.length==0
19
+ nil
20
+ else
21
+ pc
22
+ end
23
+ end.compact
24
+ end
25
+
26
+ # Get the code for the population criteria
27
+ # @return [String] the code (e.g. IPP, DEMON, NUMER, DENEX, DENEXCEP)
28
+ def code
29
+ value = attr_val('cda:observation/cda:value/@code') || HQMF::PopulationCriteria::STRAT
30
+ # exclusion population criteria has id of DENOM with actionNegationInd of true
31
+ # special case this to simply handling
32
+ if attr_val('cda:observation/@actionNegationInd')=='true' && value == HQMF::PopulationCriteria::DENOM
33
+ value = HQMF::PopulationCriteria::DENEX
34
+ end
35
+ value.upcase
36
+ end
37
+
38
+ # Get the id for the population criteria, used elsewhere in the HQMF document to
39
+ # refer to this criteria
40
+ # @return [String] the id
41
+ def id
42
+ @id
43
+ end
44
+
45
+ def title
46
+ attr_val('cda:observation/cda:value/@displayName')
47
+ end
48
+
49
+ def reference
50
+ reference = attr_val('./cda:observation/cda:sourceOf[@typeCode="PRCN"]/cda:observation[@classCode="OBS"]/cda:id/@root')
51
+ reference = reference.upcase if reference
52
+ reference
53
+ end
54
+
55
+ def to_json
56
+
57
+ json = {}
58
+ self.preconditions.compact.each do |precondition|
59
+ json[:preconditions] ||= []
60
+ json[:preconditions] << precondition.to_json
61
+ end
62
+
63
+ json[:id] = id
64
+ json[:title] = title
65
+ json[:code] = code
66
+ json[:hqmf_id] = hqmf_id if hqmf_id
67
+ json[:stratification_id] = stratification_id if stratification_id
68
+ json[:reference] = reference
69
+
70
+ {self.code => json}
71
+
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,90 @@
1
+ module HQMF1
2
+
3
+ class Precondition
4
+
5
+ include HQMF1::Utilities
6
+
7
+ attr_reader :restrictions, :preconditions, :subset, :expression, :id
8
+
9
+ def initialize(entry, parent, doc)
10
+ @doc = doc
11
+ @entry = entry
12
+ @id = attr_val('./*/cda:id/@root')
13
+ @restrictions = []
14
+
15
+ local_subset = attr_val('./cda:subsetCode/@code')
16
+ if local_subset
17
+ @subset = local_subset
18
+ end
19
+ #@subset = attr_val('./cda:subsetCode/@code')
20
+
21
+ local_restrictions = @entry.xpath('./*/cda:sourceOf[@typeCode!="PRCN" and @typeCode!="COMP"]').collect do |entry|
22
+ Restriction.new(entry, self, @doc)
23
+ end
24
+ @restrictions.concat(local_restrictions)
25
+
26
+ @expression = Expression.new(@entry) if @entry.at_xpath('./*/cda:derivationExpr')
27
+
28
+ @preconditions = @entry.xpath('./*/cda:sourceOf[@typeCode="PRCN"]').collect do |entry|
29
+ Precondition.new(entry, self, @doc)
30
+ end
31
+ check_nil_conjunction_on_child
32
+ end
33
+
34
+ # Get the conjunction code, e.g. AND, OR
35
+ # @return [String] conjunction code
36
+ def conjunction
37
+ attr_val('./cda:conjunctionCode/@code')
38
+ end
39
+
40
+ # Return whether the precondition is negated (true) or not (false)
41
+ def negation
42
+ if @entry.at_xpath('./cda:act[@actionNegationInd="true"]')
43
+ is_negation_rationale = (comparison.restrictions.map {|restriction| restriction.type }).include? 'RSON' if comparison
44
+ if is_negation_rationale
45
+ false
46
+ else
47
+ true
48
+ end
49
+ else
50
+ false
51
+ end
52
+ end
53
+
54
+ def comparison
55
+ comparison_def = @entry.at_xpath('./*/cda:sourceOf[@typeCode="COMP"]')
56
+ if comparison_def
57
+ data_criteria_id = attr_val('./*/cda:id/@root')
58
+ @comparison = Comparison.new(data_criteria_id, comparison_def, self, @doc)
59
+ end
60
+ end
61
+
62
+ def first_comparison
63
+ if comparison
64
+ return comparison
65
+ elsif @preconditions
66
+ @preconditions.each do |precondition|
67
+ first = precondition.first_comparison
68
+ if first
69
+ return first
70
+ end
71
+ end
72
+ end
73
+ return nil
74
+ end
75
+
76
+ def to_json
77
+
78
+ json = build_hash(self, [:id,:conjunction,:negation,:subset])
79
+ json[:comparison] = self.comparison.to_json if self.comparison
80
+ json[:expression] = self.expression.to_json if self.expression
81
+ json[:preconditions] = json_array(self.preconditions)
82
+ json[:restrictions] = json_array(self.restrictions)
83
+ json
84
+
85
+ end
86
+
87
+ end
88
+
89
+
90
+ end
@@ -0,0 +1,76 @@
1
+ module HQMF1
2
+ # Represents a bound within a HQMF pauseQuantity, has a value, a unit and an
3
+ # inclusive/exclusive indicator
4
+ class Value
5
+ include HQMF1::Utilities
6
+
7
+ def initialize(entry, inclusive=nil)
8
+ @entry = entry
9
+
10
+ if (inclusive.nil?)
11
+ case attr_val('./@inclusive')
12
+ when 'true'
13
+ @inclusive = true
14
+ else
15
+ @inclusive = false
16
+ end
17
+ else
18
+ @inclusive = inclusive
19
+ end
20
+
21
+ end
22
+
23
+ def value
24
+ attr_val('./@value')
25
+ end
26
+
27
+ def unit
28
+ attr_val('./@unit')
29
+ end
30
+
31
+ def inclusive?
32
+ @inclusive
33
+ end
34
+
35
+ def to_json
36
+ build_hash(self, [:value,:unit,:inclusive?])
37
+ end
38
+ end
39
+
40
+ # Represents a HQMF pauseQuantity which can have low and high bounds
41
+ class Range
42
+ include HQMF1::Utilities
43
+ attr_reader :low, :high
44
+
45
+ def initialize(entry)
46
+ @entry = entry
47
+ if @entry
48
+ @low = optional_value('./cda:low')
49
+ @high = optional_value('./cda:high')
50
+ if (@low == nil && @high == nil)
51
+ @low = optional_value('.',true)
52
+ @high = optional_value('.',true)
53
+ end
54
+ end
55
+ end
56
+
57
+ def to_json
58
+ json = {}
59
+ json[:low] = self.low.to_json if self.low
60
+ json[:high] = self.high.to_json if self.high
61
+ json
62
+ end
63
+
64
+ private
65
+
66
+ def optional_value(xpath, inclusive=nil)
67
+ value_def = @entry.at_xpath(xpath)
68
+ if value_def
69
+ Value.new(value_def, inclusive)
70
+ else
71
+ nil
72
+ end
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,162 @@
1
+ module HQMF1
2
+ # Represents a restriction on the allowable values of a data item
3
+ class Restriction
4
+
5
+ include HQMF1::Utilities
6
+
7
+ attr_reader :range, :comparison, :restrictions, :subset, :preconditions, :expression
8
+ attr_accessor :from_parent
9
+
10
+ def initialize(entry, parent, doc)
11
+ @doc = doc
12
+ @entry = entry
13
+ @restrictions = []
14
+
15
+ range_def = @entry.at_xpath('./cda:pauseQuantity')
16
+ if range_def
17
+ @range = Range.new(range_def)
18
+ end
19
+
20
+ local_restrictions = @entry.xpath('./*/cda:sourceOf[@typeCode!="PRCN" and @typeCode!="COMP"]').collect do |entry|
21
+ Restriction.new(entry, self, @doc)
22
+ end
23
+
24
+ @restrictions.concat(local_restrictions)
25
+
26
+ local_subset = attr_val('./cda:subsetCode/@code')
27
+ if local_subset
28
+ @subset = local_subset
29
+ end
30
+
31
+ if @entry.at_xpath('./*/cda:derivationExpr')
32
+ @expression = Expression.new(@entry)
33
+ end
34
+
35
+ comparison_def = @entry.at_xpath('./*/cda:sourceOf[@typeCode="COMP"]')
36
+ if comparison_def
37
+ data_criteria_id = attr_val('./*/cda:id/@root')
38
+ data_criteria_id = comparison_def.at_xpath('./*/cda:id/@root').value if (data_criteria_id.nil? and comparison_def.at_xpath('./*/cda:id/@root'))
39
+ @comparison = Comparison.new(data_criteria_id, comparison_def, self, @doc)
40
+ end
41
+
42
+ @preconditions = @entry.xpath('./*/cda:sourceOf[@typeCode="PRCN"]').collect do |entry|
43
+ # create a dummy parent with a single restriction copied from self minus the
44
+ # nested preconditions to avoid an infinite loop
45
+ prior_comparison = nil
46
+ if parent.class==HQMF1::Precondition
47
+ prior_comparison = parent.first_comparison
48
+ else
49
+ prior_comparison = @comparsion
50
+ end
51
+ current_restriction = OpenStruct.new(
52
+ 'range' => @range,
53
+ 'comparison' => prior_comparison,
54
+ 'restrictions' => [],
55
+ 'preconditions' => [],
56
+ 'subset' => @subset,
57
+ 'type' => type,
58
+ 'target_id' => target_id,
59
+ 'field' => field,
60
+ 'field_code' => field_code,
61
+ 'field_time' => field_time,
62
+ 'value' => value)
63
+ all_restrictions = []
64
+ all_restrictions.concat @restrictions
65
+ all_restrictions << current_restriction
66
+ parent = OpenStruct.new(
67
+ 'restrictions' => all_restrictions,
68
+ 'subset' => @subset
69
+ )
70
+ p = Precondition.new(entry, parent, @doc)
71
+
72
+ end
73
+
74
+ check_nil_conjunction_on_child
75
+
76
+ end
77
+
78
+ # The type of restriction, e.g. SBS, SBE etc
79
+ def type
80
+ attr_val('./@typeCode')
81
+ end
82
+
83
+ # is this type negated? true or false
84
+ def negation
85
+ attr_val('./@inversionInd') == "true"
86
+ end
87
+
88
+ # The id of the data criteria or measurement property that the value
89
+ # will be compared against
90
+ def target_id
91
+ attr_val('./*/cda:id/@root')
92
+ end
93
+
94
+ def field
95
+ attr_val('./cda:observation/cda:code/@displayName')
96
+ end
97
+
98
+ def field_code
99
+ attr_val('./cda:observation/cda:code/@code') || attr_val('./cda:encounter/cda:participant/cda:roleParticipant/@classCode')
100
+ end
101
+
102
+ def field_time
103
+ effectiveTime = @entry.at_xpath('./cda:observation/cda:effectiveTime') || @entry.at_xpath('./cda:encounter/cda:participant/cda:roleParticipant/cda:effectiveTime')
104
+
105
+ time = nil
106
+ if effectiveTime
107
+ time = :start if effectiveTime.at_xpath('./cda:low')
108
+ time = :end if effectiveTime.at_xpath('./cda:high')
109
+ end
110
+ time
111
+ end
112
+
113
+
114
+ def value
115
+ value = nil
116
+ type = attr_val('./cda:observation/cda:value/@xsi:type') || 'CD'
117
+ case type
118
+ when 'IVL_PQ'
119
+ value = HQMF1::Range.new(@entry.xpath('./cda:observation/cda:value'))
120
+ when 'PQ'
121
+ value = HQMF1::Value.new(@entry.xpath('./cda:observation/cda:value'))
122
+ when 'CD'
123
+ if field && field.downcase == 'status'
124
+ code = attr_val('./cda:observation/cda:value/@displayName').downcase
125
+ value = HQMF::Coded.for_single_code('status',code,code)
126
+ elsif attr_val('./cda:observation/cda:value/@code')
127
+ oid = attr_val('./cda:observation/cda:value/@code')
128
+ title = attr_val('./cda:observation/cda:value/@displayName')
129
+ value = HQMF::Coded.for_code_list(oid,title)
130
+ elsif attr_val('./cda:encounter/cda:participant/cda:roleParticipant/cda:code/@code')
131
+ oid = attr_val('./cda:encounter/cda:participant/cda:roleParticipant/cda:code/@code')
132
+ title = attr_val('./cda:encounter/cda:participant/cda:roleParticipant/cda:code/@displayName')
133
+ value = HQMF::Coded.for_code_list(oid,title)
134
+ end
135
+ when 'ANYNonNull'
136
+ value = HQMF::AnyValue.new
137
+ else
138
+ raise "Unknown restriction value type #{type}"
139
+ end if type
140
+ value
141
+ end
142
+
143
+ def to_json
144
+ return nil if from_parent
145
+ json = build_hash(self, [:subset,:type,:target_id,:field,:field_code,:from_parent, :negation, :field_time])
146
+ json[:range] = range.to_json if range
147
+ if value
148
+ if value.is_a? String
149
+ json[:value] = value
150
+ else
151
+ json[:value] = value.to_json
152
+ end
153
+ end
154
+ json[:comparison] = comparison.to_json if comparison
155
+ json[:restrictions] = json_array(self.restrictions)
156
+ json[:preconditions] = json_array(self.preconditions)
157
+ json[:expression] = self.expression.to_json if self.expression
158
+ json
159
+ end
160
+
161
+ end
162
+ end