hqmf-parser 1.0.0
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.
- data/Gemfile +23 -0
- data/README.md +903 -0
- data/Rakefile +19 -0
- data/VERSION +1 -0
- data/lib/hqmf-generator/hqmf-generator.rb +308 -0
- data/lib/hqmf-model/attribute.rb +35 -0
- data/lib/hqmf-model/data_criteria.rb +322 -0
- data/lib/hqmf-model/document.rb +172 -0
- data/lib/hqmf-model/population_criteria.rb +90 -0
- data/lib/hqmf-model/precondition.rb +85 -0
- data/lib/hqmf-model/types.rb +318 -0
- data/lib/hqmf-model/utilities.rb +52 -0
- data/lib/hqmf-parser.rb +54 -0
- data/lib/hqmf-parser/1.0/attribute.rb +68 -0
- data/lib/hqmf-parser/1.0/comparison.rb +34 -0
- data/lib/hqmf-parser/1.0/data_criteria.rb +105 -0
- data/lib/hqmf-parser/1.0/document.rb +209 -0
- data/lib/hqmf-parser/1.0/expression.rb +52 -0
- data/lib/hqmf-parser/1.0/population_criteria.rb +79 -0
- data/lib/hqmf-parser/1.0/precondition.rb +89 -0
- data/lib/hqmf-parser/1.0/range.rb +65 -0
- data/lib/hqmf-parser/1.0/restriction.rb +157 -0
- data/lib/hqmf-parser/1.0/utilities.rb +41 -0
- data/lib/hqmf-parser/2.0/data_criteria.rb +319 -0
- data/lib/hqmf-parser/2.0/document.rb +165 -0
- data/lib/hqmf-parser/2.0/population_criteria.rb +53 -0
- data/lib/hqmf-parser/2.0/precondition.rb +44 -0
- data/lib/hqmf-parser/2.0/types.rb +223 -0
- data/lib/hqmf-parser/2.0/utilities.rb +30 -0
- data/lib/hqmf-parser/converter/pass1/data_criteria_converter.rb +254 -0
- data/lib/hqmf-parser/converter/pass1/document_converter.rb +183 -0
- data/lib/hqmf-parser/converter/pass1/population_criteria_converter.rb +135 -0
- data/lib/hqmf-parser/converter/pass1/precondition_converter.rb +164 -0
- data/lib/hqmf-parser/converter/pass1/precondition_extractor.rb +159 -0
- data/lib/hqmf-parser/converter/pass1/simple_data_criteria.rb +35 -0
- data/lib/hqmf-parser/converter/pass1/simple_operator.rb +89 -0
- data/lib/hqmf-parser/converter/pass1/simple_population_criteria.rb +10 -0
- data/lib/hqmf-parser/converter/pass1/simple_precondition.rb +63 -0
- data/lib/hqmf-parser/converter/pass1/simple_restriction.rb +64 -0
- data/lib/hqmf-parser/converter/pass2/comparison_converter.rb +91 -0
- data/lib/hqmf-parser/converter/pass2/operator_converter.rb +169 -0
- data/lib/hqmf-parser/converter/pass3/specific_occurrence_converter.rb +86 -0
- data/lib/hqmf-parser/converter/pass3/specific_occurrence_converter_bak.rb +70 -0
- data/lib/hqmf-parser/parser.rb +22 -0
- data/lib/hqmf-parser/value_sets/value_set_parser.rb +206 -0
- data/lib/tasks/coverme.rake +8 -0
- data/lib/tasks/hqmf.rake +141 -0
- data/lib/tasks/value_sets.rake +23 -0
- metadata +159 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
module HQMF
|
2
|
+
|
3
|
+
# preconditions can be in several places.
|
4
|
+
#
|
5
|
+
# precondition -> preconditions
|
6
|
+
# restriction -> preconditions
|
7
|
+
#
|
8
|
+
# also, restrictions can be on the following, which can then have preconditions
|
9
|
+
# restrictions
|
10
|
+
# comparisons
|
11
|
+
# preconditions
|
12
|
+
#
|
13
|
+
class PreconditionExtractor
|
14
|
+
|
15
|
+
|
16
|
+
def self.extract_preconditions_from_restrictions(restrictions,data_criteria_converter)
|
17
|
+
return [] unless restrictions
|
18
|
+
preconditions = []
|
19
|
+
restrictions.each do |restriction|
|
20
|
+
preconditions.concat(extract_preconditions_from_restriction(restriction,data_criteria_converter))
|
21
|
+
end
|
22
|
+
preconditions
|
23
|
+
end
|
24
|
+
|
25
|
+
# get all the preconditions for a restriction
|
26
|
+
# we need to iterate down
|
27
|
+
# restriction.preconditions
|
28
|
+
# restriction.comparison
|
29
|
+
# restriction.restriction
|
30
|
+
def self.extract_preconditions_from_restriction(restriction,data_criteria_converter)
|
31
|
+
|
32
|
+
target_id = data_criteria_converter.v1_data_criteria_by_id[restriction[:target_id]].id if restriction[:target_id]
|
33
|
+
type = restriction[:type]
|
34
|
+
if (restriction[:negation])
|
35
|
+
inverted = HQMF::TemporalReference::INVERSION[type]
|
36
|
+
if (inverted)
|
37
|
+
type = inverted
|
38
|
+
else
|
39
|
+
puts "\tdon't know how to invert #{type}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# if we reference the measurement period, then we want to check if the reference is to the start or end of the measurement period
|
44
|
+
# if we SBS of the END of the measurement period, we want to convert that to SBE of the measurement period
|
45
|
+
if target_id == HQMF::Document::MEASURE_PERIOD_ID
|
46
|
+
references_start = {'SBS'=>'SBE','SAS'=>'SAE','EBS'=>'EBE','EAS'=>'EAE'}
|
47
|
+
references_end = {'EBE'=>'EBS','EAE'=>'EAS','SBE'=>'SBS','SAE'=>'SAS'}
|
48
|
+
if data_criteria_converter.measure_period_v1_keys[:measure_start] == restriction[:target_id] and references_end[type]
|
49
|
+
# before or after the END of the measurement period START. Convert to before or after the START of the measurement period.
|
50
|
+
# SAE of MPS => SAS of MP
|
51
|
+
type = references_end[type]
|
52
|
+
elsif data_criteria_converter.measure_period_v1_keys[:measure_end] == restriction[:target_id] and references_start[type]
|
53
|
+
# before or after the START of the measurement period END. Convert to before or after the END of the measurement period.
|
54
|
+
# SBS of MPE => SBE of MP
|
55
|
+
type = references_start[type]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
value = nil
|
60
|
+
if (restriction[:range])
|
61
|
+
value = HQMF::Range.from_json(JSON.parse(restriction[:range].to_json)) if (restriction[:range])
|
62
|
+
elsif(restriction[:value])
|
63
|
+
value = HQMF::Converter::SimpleOperator.parse_value(restriction[:value])
|
64
|
+
end
|
65
|
+
field = restriction[:field]
|
66
|
+
field_code = restriction[:field_code]
|
67
|
+
field_time = restriction[:field_time]
|
68
|
+
operator = HQMF::Converter::SimpleOperator.new(HQMF::Converter::SimpleOperator.find_category(type), type, value, field, field_code, field_time)
|
69
|
+
|
70
|
+
# get the precondtions off of the restriction
|
71
|
+
children = HQMF::PreconditionConverter.parse_and_merge_preconditions(restriction[:preconditions],data_criteria_converter) if restriction[:preconditions]
|
72
|
+
|
73
|
+
if restriction[:comparison]
|
74
|
+
children ||= []
|
75
|
+
# check comparison and convert it to a precondition
|
76
|
+
comparison = convert_comparison_to_precondition(restriction[:comparison], data_criteria_converter)
|
77
|
+
children << comparison
|
78
|
+
end
|
79
|
+
|
80
|
+
# check restrictions
|
81
|
+
restrictions = extract_preconditions_from_restrictions(restriction[:restrictions], data_criteria_converter) if restriction[:restrictions]
|
82
|
+
HQMF::PreconditionConverter.apply_restrictions_to_comparisons(children, restrictions) unless restrictions.nil? or restrictions.empty?
|
83
|
+
|
84
|
+
container = nil
|
85
|
+
# check if there is a subset on the restriction
|
86
|
+
if restriction[:subset]
|
87
|
+
# if we have a subset, we want to create a Comparison Precondition for the subset and have it be the child of the operator on the restriction.
|
88
|
+
# the reason for this is that we want the order of operations to be SBS the FIRST of a data criteria, rather than FIRST of SBS of a data criteria
|
89
|
+
|
90
|
+
subset_type = restriction[:subset]
|
91
|
+
subset_operator = HQMF::Converter::SimpleOperator.new(HQMF::Converter::SimpleOperator.find_category(subset_type), subset_type, nil)
|
92
|
+
|
93
|
+
reference = nil
|
94
|
+
# conjunction_code = "operator"
|
95
|
+
conjunction_code = nil
|
96
|
+
|
97
|
+
restriction = HQMF::Converter::SimpleRestriction.new(subset_operator, target_id)
|
98
|
+
restriction.preconditions = children
|
99
|
+
|
100
|
+
comparison_precondition = HQMF::Converter::SimplePrecondition.new(nil, [restriction], reference, conjunction_code, false)
|
101
|
+
comparison_precondition.klass = HQMF::Converter::SimplePrecondition::COMPARISON
|
102
|
+
|
103
|
+
container = HQMF::Converter::SimpleRestriction.new(operator, nil, [comparison_precondition])
|
104
|
+
else
|
105
|
+
container = HQMF::Converter::SimpleRestriction.new(operator, target_id)
|
106
|
+
container.preconditions = children
|
107
|
+
end
|
108
|
+
|
109
|
+
[container]
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# we want the comparisons to be converted to the leaf preconditions
|
114
|
+
def self.convert_comparison_to_precondition(comparison, data_criteria_converter)
|
115
|
+
|
116
|
+
data_criteria = data_criteria_converter.v1_data_criteria_by_id[comparison[:data_criteria_id]]
|
117
|
+
reference = HQMF::Reference.new(data_criteria.id)
|
118
|
+
# conjunction_code = "#{data_criteria.type.to_s.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }}Reference"
|
119
|
+
conjunction_code = nil
|
120
|
+
|
121
|
+
preconditions = []
|
122
|
+
if comparison[:restrictions]
|
123
|
+
# check for preconditions on restrictions
|
124
|
+
preconditions = extract_preconditions_from_restrictions(comparison[:restrictions], data_criteria_converter)
|
125
|
+
end
|
126
|
+
|
127
|
+
precondition = HQMF::Converter::SimplePrecondition.new(nil,preconditions,reference,conjunction_code, false)
|
128
|
+
precondition.klass = HQMF::Converter::SimplePrecondition::COMPARISON
|
129
|
+
|
130
|
+
if (comparison[:subset])
|
131
|
+
# create a restriction for a comparison subset... this is for things like first, second, etc.
|
132
|
+
type = comparison[:subset]
|
133
|
+
operator = HQMF::Converter::SimpleOperator.new(HQMF::Converter::SimpleOperator.find_category(type), type, nil)
|
134
|
+
restriction = HQMF::Converter::SimpleRestriction.new(operator, reference.id, nil)
|
135
|
+
precondition.preconditions ||= []
|
136
|
+
precondition.preconditions << restriction
|
137
|
+
end
|
138
|
+
|
139
|
+
precondition
|
140
|
+
end
|
141
|
+
|
142
|
+
# flatten a tree of preconditions into an array... if we are doing something like a count, we just want the flat list
|
143
|
+
def self.flatten_v2_preconditions(preconditions)
|
144
|
+
flattened = []
|
145
|
+
preconditions.each do |precondition|
|
146
|
+
if (precondition.reference and precondition.has_preconditions?)
|
147
|
+
raise "don't know how to handle a condition with a reference that has preconditions" if (precondition.reference and precondition.has_preconditions?)
|
148
|
+
end
|
149
|
+
if (precondition.reference)
|
150
|
+
flattened << precondition
|
151
|
+
else
|
152
|
+
flattened.concat(flatten_v2_preconditions(precondition.preconditions))
|
153
|
+
end
|
154
|
+
end
|
155
|
+
flattened
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module HQMF
|
2
|
+
|
3
|
+
module Converter
|
4
|
+
|
5
|
+
class SimpleDataCriteria < HQMF::DataCriteria
|
6
|
+
|
7
|
+
attr_accessor :precondition_id
|
8
|
+
|
9
|
+
def self.from_data_criteria(data_criteria)
|
10
|
+
description = get_description(data_criteria)
|
11
|
+
|
12
|
+
HQMF::Converter::SimpleDataCriteria.new(data_criteria.id, data_criteria.title, data_criteria.display_name, description, data_criteria.code_list_id,
|
13
|
+
data_criteria.children_criteria, data_criteria.derivation_operator, data_criteria.definition,data_criteria.status, data_criteria.value, data_criteria.field_values,
|
14
|
+
data_criteria.effective_time, data_criteria.inline_code_list,data_criteria.negation,data_criteria.negation_code_list_id,data_criteria.temporal_references, data_criteria.subset_operators, data_criteria.specific_occurrence,data_criteria.specific_occurrence_const)
|
15
|
+
end
|
16
|
+
|
17
|
+
def assign_precondition(precondtion_id)
|
18
|
+
return if (@precondtion_id == precondtion_id)
|
19
|
+
raise "Cannot assign a second precondition to a data criteria" if @precondition_id
|
20
|
+
@precondition_id = precondtion_id
|
21
|
+
@id = "#{@id}_precondition_#{precondtion_id}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.get_description(data_criteria)
|
25
|
+
description = data_criteria.description
|
26
|
+
status = ", #{data_criteria.status.titleize}" if data_criteria.status
|
27
|
+
description = "#{data_criteria.definition.titleize}#{status}: #{data_criteria.description}" if (data_criteria.description.downcase.match /#{data_criteria.definition.titleize.downcase}/).nil? and (data_criteria.description.downcase.match /#{data_criteria.status}/).nil?
|
28
|
+
description
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module HQMF
|
2
|
+
|
3
|
+
module Converter
|
4
|
+
|
5
|
+
class SimpleOperator
|
6
|
+
|
7
|
+
TEMPORAL = 'TEMPORAL'
|
8
|
+
SUMMARY = 'SUMMARY'
|
9
|
+
UNKNOWN = 'UNKNOWN'
|
10
|
+
|
11
|
+
VALUE_FIELD_TIMES = {
|
12
|
+
'FACILITY_LOCATION_START' => 'FACILITY_LOCATION_ARRIVAL_DATETIME',
|
13
|
+
'FACILITY_LOCATION_END' => 'FACILITY_LOCATION_DEPARTURE_DATETIME'
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
attr_accessor :type, :value, :category, :field, :field_code, :field_time
|
18
|
+
|
19
|
+
def initialize(category, type, value, field = nil, field_code=nil, field_time=nil)
|
20
|
+
@category = category
|
21
|
+
@type = type
|
22
|
+
@value = value
|
23
|
+
@field = field
|
24
|
+
@field_code = field_code
|
25
|
+
@field_time = field_time
|
26
|
+
end
|
27
|
+
|
28
|
+
def temporal?
|
29
|
+
category == TEMPORAL
|
30
|
+
end
|
31
|
+
def summary?
|
32
|
+
category == SUMMARY
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_json
|
36
|
+
json = {}
|
37
|
+
json[:category] = @category if @category
|
38
|
+
json[:type] = @type if @type
|
39
|
+
json[:field] = @field if @field
|
40
|
+
json[:field_code] = @field_code if @field_code
|
41
|
+
json[:value] = @value.to_json if @value
|
42
|
+
json
|
43
|
+
end
|
44
|
+
|
45
|
+
def field_value_key
|
46
|
+
key = HQMF::DataCriteria::VALUE_FIELDS[field_code]
|
47
|
+
key = VALUE_FIELD_TIMES["#{key}_#{field_time.to_s.upcase}"] if (field_time)
|
48
|
+
raise "unsupported field value: #{field_code}, #{field}" unless key
|
49
|
+
key
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.parse_value(value)
|
53
|
+
return nil unless value
|
54
|
+
return value if value.is_a? String
|
55
|
+
if (value[:value])
|
56
|
+
# values should be inclusive since we will be asking if it equals the value, ranther than being part of a range
|
57
|
+
# if it's an offset we do not care that it is inclusive
|
58
|
+
val = HQMF::Value.from_json(JSON.parse(value.to_json))
|
59
|
+
val.inclusive=true
|
60
|
+
val
|
61
|
+
elsif (value[:high] or value[:low])
|
62
|
+
HQMF::Range.from_json(JSON.parse(value.to_json))
|
63
|
+
elsif (value[:type] == 'CD')
|
64
|
+
HQMF::Coded.from_json(JSON.parse(value.to_json))
|
65
|
+
elsif (value[:type] == 'ANYNonNull')
|
66
|
+
HQMF::AnyValue.from_json(JSON.parse(value.to_json))
|
67
|
+
else
|
68
|
+
raise "Unexpected value format: #{value.to_json}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.find_category(type)
|
73
|
+
return TEMPORAL if HQMF::TemporalReference::TYPES.include? type
|
74
|
+
return SUMMARY if HQMF::SubsetOperator::TYPES.include? type
|
75
|
+
return UNKNOWN
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module HQMF
|
2
|
+
|
3
|
+
module Converter
|
4
|
+
|
5
|
+
class SimplePrecondition < HQMF::Precondition
|
6
|
+
|
7
|
+
COMPARISON = "COMPARISON"
|
8
|
+
PRECONDITION = "PRECONDITION"
|
9
|
+
|
10
|
+
attr_accessor :klass, :processed, :subset_comparison
|
11
|
+
|
12
|
+
def initialize(id, preconditions,reference,conjunction_code,negation)
|
13
|
+
super(id, preconditions,reference,conjunction_code,negation)
|
14
|
+
@id = @@ids.next if (@id.nil?)
|
15
|
+
@klass = PRECONDITION
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json
|
19
|
+
json = super
|
20
|
+
# json[:klass] = @klass
|
21
|
+
json
|
22
|
+
end
|
23
|
+
|
24
|
+
def comparison?
|
25
|
+
@klass == COMPARISON
|
26
|
+
end
|
27
|
+
def restriction?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_preconditions?
|
32
|
+
preconditions and !preconditions.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
def restrictions
|
36
|
+
preconditions.select {|precondition| precondition.restriction?}
|
37
|
+
end
|
38
|
+
|
39
|
+
def reference=(reference)
|
40
|
+
@reference = reference
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete_converted_restrictions!
|
44
|
+
preconditions.delete_if {|precondition| precondition.restriction? and precondition.converted}
|
45
|
+
end
|
46
|
+
|
47
|
+
# Simple class to issue monotonically increasing integer identifiers
|
48
|
+
class Counter
|
49
|
+
def initialize
|
50
|
+
@count = 0
|
51
|
+
end
|
52
|
+
|
53
|
+
def next
|
54
|
+
@count+=1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
@@ids = Counter.new
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module HQMF
|
2
|
+
|
3
|
+
module Converter
|
4
|
+
|
5
|
+
class SimpleRestriction
|
6
|
+
|
7
|
+
include HQMF::Conversion::Utilities
|
8
|
+
|
9
|
+
attr_accessor :operator, :target, :preconditions, :negation, :converted, :generated_data_criteria
|
10
|
+
def initialize(operator, target, preconditions = [])
|
11
|
+
@operator = operator
|
12
|
+
@target = target
|
13
|
+
@preconditions = preconditions
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create a new population criteria from a JSON hash keyed off symbols
|
17
|
+
def self.from_json(json)
|
18
|
+
raise "not implemented"
|
19
|
+
end
|
20
|
+
|
21
|
+
def klass
|
22
|
+
"RESTRICTION"
|
23
|
+
end
|
24
|
+
|
25
|
+
def comparison?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
def restriction?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_preconditions?
|
33
|
+
preconditions and !preconditions.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
def single_target?
|
37
|
+
!target.nil?
|
38
|
+
end
|
39
|
+
def multi_target?
|
40
|
+
has_preconditions?
|
41
|
+
end
|
42
|
+
|
43
|
+
def restrictions
|
44
|
+
preconditions.select {|precondition| precondition.restriction?}
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_json
|
48
|
+
x = nil
|
49
|
+
json = {}
|
50
|
+
json[:klass] = klass
|
51
|
+
json[:operator] = @operator.to_json if @operator
|
52
|
+
json[:target] = @target if @target
|
53
|
+
json[:negation] = @negation if @negation
|
54
|
+
if (@preconditions)
|
55
|
+
json[:preconditions] = x if x = json_array(@preconditions)
|
56
|
+
end
|
57
|
+
json
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module HQMF
|
2
|
+
# Class for converting an HQMF 1.0 representation to an HQMF 2.0 representation
|
3
|
+
class ComparisonConverter
|
4
|
+
|
5
|
+
def initialize(data_criteria_converter)
|
6
|
+
@data_criteria_converter = data_criteria_converter
|
7
|
+
end
|
8
|
+
|
9
|
+
def convert_comparisons(population_criteria)
|
10
|
+
population_criteria.each do |population|
|
11
|
+
walk_up_tree(population.preconditions)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def walk_up_tree(preconditions)
|
16
|
+
preconditions.each do |precondition|
|
17
|
+
if (has_child_comparison(precondition))
|
18
|
+
walk_up_tree(precondition.preconditions)
|
19
|
+
end
|
20
|
+
if (precondition.comparison? && !precondition.processed)
|
21
|
+
new_data_criteria = nil
|
22
|
+
# duplicate the data criteria referenced by the comparision (unless it's the measurement period. we don't modify the measurement period)
|
23
|
+
if precondition.reference and precondition.reference.id != HQMF::Document::MEASURE_PERIOD_ID
|
24
|
+
data_criteria = @data_criteria_converter.v2_data_criteria_by_id[precondition.reference.id]
|
25
|
+
new_data_criteria = @data_criteria_converter.duplicate_data_criteria(data_criteria, precondition.id)
|
26
|
+
precondition.reference.id = new_data_criteria.id
|
27
|
+
end
|
28
|
+
# add restrictions to the duplicated data criteria
|
29
|
+
if precondition.has_preconditions?
|
30
|
+
restrictions = precondition.restrictions
|
31
|
+
# we want to process summary operators first since they can create new data criteria
|
32
|
+
restrictions.sort! {|left, right| (right.operator.summary? and !left.operator.summary?) ? 1 : 0 }
|
33
|
+
restrictions.each do |restriction|
|
34
|
+
operator = restriction.operator
|
35
|
+
# check if the data criteria has been changed by either a grouping addition or an operator
|
36
|
+
if (precondition.reference and (new_data_criteria == nil or new_data_criteria.id != precondition.reference.id))
|
37
|
+
new_data_criteria = @data_criteria_converter.v2_data_criteria_by_id[precondition.reference.id]
|
38
|
+
end
|
39
|
+
if (operator.temporal?)
|
40
|
+
HQMF::OperatorConverter.apply_temporal(new_data_criteria, precondition, restriction, @data_criteria_converter)
|
41
|
+
elsif(operator.summary?)
|
42
|
+
HQMF::OperatorConverter.apply_summary(new_data_criteria, precondition, restriction, @data_criteria_converter)
|
43
|
+
else
|
44
|
+
case operator.type
|
45
|
+
when 'REFR'
|
46
|
+
if operator.field.downcase == 'status'
|
47
|
+
# only set the status if we don't have one. We trust the template ID statuses more than the restrictions
|
48
|
+
new_data_criteria.status ||= operator.value.code
|
49
|
+
elsif operator.field.downcase == 'result value' or operator.field.downcase == 'result'
|
50
|
+
puts "\tREFR result value is nil: #{new_data_criteria.title}" if (operator.value.nil?)
|
51
|
+
new_data_criteria.value = operator.value
|
52
|
+
else
|
53
|
+
new_data_criteria.field_values ||= {}
|
54
|
+
new_data_criteria.field_values[operator.field_value_key] = operator.value
|
55
|
+
end
|
56
|
+
restriction.converted=true
|
57
|
+
when 'RSON'
|
58
|
+
new_data_criteria.negation_code_list_id = operator.value.code_list_id
|
59
|
+
new_data_criteria.negation=true
|
60
|
+
restriction.converted=true
|
61
|
+
when 'SUBJ'
|
62
|
+
new_data_criteria.field_values ||= {}
|
63
|
+
new_data_criteria.field_values[operator.field_value_key] = operator.value
|
64
|
+
restriction.converted=true
|
65
|
+
else
|
66
|
+
puts "\tOperator is unknown: #{operator.type}"
|
67
|
+
restriction.converted=true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
precondition.delete_converted_restrictions!
|
72
|
+
precondition.processed = true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def has_child_comparison(node)
|
79
|
+
value = false
|
80
|
+
node.preconditions.each do |precondition|
|
81
|
+
if (precondition.comparison?)
|
82
|
+
value ||= true
|
83
|
+
elsif precondition.has_preconditions?
|
84
|
+
value ||= has_child_comparison(precondition)
|
85
|
+
end
|
86
|
+
end if node.preconditions
|
87
|
+
value
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|