cqm-reports 2.1.1 → 3.0.0.pre.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +1 -2
- data/README.md +0 -27
- data/lib/{cqm_report.rb → cqm-reports.rb} +4 -2
- data/lib/ext/code.rb +11 -0
- data/lib/ext/data_element.rb +24 -0
- data/lib/html-export/qdm-patient/qdm_patient.rb +3 -3
- data/lib/qrda-export/catI-r5/_header.mustache +2 -2
- data/lib/qrda-export/catI-r5/qrda1_r5.mustache +2 -6
- data/lib/qrda-export/catI-r5/qrda1_r5.rb +2 -28
- data/lib/qrda-export/catI-r5/qrda_header/_record_target.mustache +11 -24
- data/lib/qrda-export/catI-r5/qrda_templates/adverse_event.mustache +4 -4
- data/lib/qrda-export/catI-r5/qrda_templates/allergy_intolerance.mustache +6 -1
- data/lib/qrda-export/catI-r5/qrda_templates/communication_performed.mustache +2 -2
- data/lib/qrda-export/catI-r5/qrda_templates/diagnosis.mustache +6 -1
- data/lib/qrda-export/catI-r5/qrda_templates/encounter_performed.mustache +0 -4
- data/lib/qrda-export/catI-r5/qrda_templates/immunization_administered.mustache +2 -7
- data/lib/qrda-export/catI-r5/qrda_templates/medication_discharge.mustache +2 -0
- data/lib/qrda-export/catI-r5/qrda_templates/procedure_order.mustache +0 -4
- data/lib/qrda-export/catI-r5/qrda_templates/procedure_performed.mustache +0 -4
- data/lib/qrda-export/catI-r5/qrda_templates/procedure_recommended.mustache +0 -4
- data/lib/qrda-export/catI-r5/qrda_templates/substance_recommended.mustache +0 -1
- data/lib/qrda-export/catI-r5/qrda_templates/symptom.mustache +6 -1
- data/lib/qrda-export/catI-r5/qrda_templates/template_partials/_encounter_diagnosis.mustache +3 -1
- data/lib/qrda-export/catI-r5/qrda_templates/template_partials/_medication_supply_request.mustache +1 -1
- data/lib/qrda-export/catI-r5/qrda_templates/template_partials/_results.mustache +12 -0
- data/lib/qrda-export/helper/cat1_view_helper.rb +4 -6
- data/lib/qrda-export/helper/date_helper.rb +4 -0
- data/lib/qrda-import/base-importers/demographics_importer.rb +4 -4
- data/lib/qrda-import/base-importers/section_importer.rb +14 -58
- data/lib/qrda-import/data-element-importers/adverse_event_importer.rb +1 -1
- data/lib/qrda-import/data-element-importers/communication_performed_importer.rb +4 -4
- data/lib/qrda-import/data-element-importers/diagnostic_study_performed_importer.rb +1 -1
- data/lib/qrda-import/data-element-importers/encounter_performed_importer.rb +0 -12
- data/lib/qrda-import/data-element-importers/immunization_order_importer.rb +1 -1
- data/lib/qrda-import/data-element-importers/medication_dispensed_importer.rb +2 -2
- data/lib/qrda-import/data-element-importers/medication_order_importer.rb +1 -1
- data/lib/qrda-import/data-element-importers/procedure_order_importer.rb +0 -2
- data/lib/qrda-import/data-element-importers/procedure_performed_importer.rb +0 -2
- data/lib/qrda-import/data-element-importers/procedure_recommended_importer.rb +0 -2
- data/lib/qrda-import/entry_package.rb +16 -0
- data/lib/qrda-import/patient_importer.rb +62 -85
- metadata +15 -29
- data/lib/qrda-export/catI-r5/qrda_templates/provider_characteristic.mustache +0 -15
- data/lib/qrda-import/data-element-importers/provider_characteristic_importer.rb +0 -19
@@ -6,7 +6,6 @@
|
|
6
6
|
<templateId root="2.16.840.1.113883.10.20.24.3.75" extension="2017-08-01"/>
|
7
7
|
<id root="1.3.6.1.4.1.115" extension="{{object_id}}"/>
|
8
8
|
<statusCode code="active"/>
|
9
|
-
{{{author_effective_time}}}
|
10
9
|
{{> qrda_templates/template_partials/_medication_details}}
|
11
10
|
<consumable>
|
12
11
|
<manufacturedProduct classCode="MANU">
|
@@ -25,8 +25,13 @@
|
|
25
25
|
<code code="75325-1" codeSystem="2.16.840.1.113883.6.1">
|
26
26
|
<translation code="418799008" displayName="Symptom" codeSystem="2.16.840.1.113883.6.96"/>
|
27
27
|
</code>
|
28
|
-
<statusCode code="completed" />
|
29
28
|
{{#prevalencePeriod}}
|
29
|
+
{{#completed_prevalence_period}}
|
30
|
+
<statusCode code="completed" />
|
31
|
+
{{/completed_prevalence_period}}
|
32
|
+
{{^completed_prevalence_period}}
|
33
|
+
<statusCode code="active" />
|
34
|
+
{{/completed_prevalence_period}}
|
30
35
|
<!-- QDM Attribute: Prevalence Period -->
|
31
36
|
{{{prevalence_period}}}
|
32
37
|
{{/prevalencePeriod}}
|
data/lib/qrda-export/catI-r5/qrda_templates/template_partials/_medication_supply_request.mustache
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
<supply classCode="SPLY" moodCode="RQO">
|
2
2
|
<!-- Medication Supply Request (V2) template -->
|
3
|
-
<templateId root="2.16.840.1.113883.10.20.24.3.99" extension="
|
3
|
+
<templateId root="2.16.840.1.113883.10.20.24.3.99" extension="2014-04-05"/>
|
4
4
|
<!-- Conforms to C-CDA R2 Planned Supply (V2) template-->
|
5
5
|
<templateId root="2.16.840.1.113883.10.20.22.4.43" extension="2014-06-09" />
|
6
6
|
<id root="{{random_id}}"/>
|
@@ -5,7 +5,19 @@
|
|
5
5
|
<id root="1.3.6.1.4.1.115" extension="{{random_id}}"/>
|
6
6
|
{{> _codes}}
|
7
7
|
<statusCode code="completed"/>
|
8
|
+
{{#resultDatetime}}
|
8
9
|
{{{result_date_time}}}
|
10
|
+
{{/resultDatetime}}
|
11
|
+
{{^resultDatetime}}
|
12
|
+
{{#relevantPeriod}}
|
13
|
+
{{{relevant_period_as_value}}}
|
14
|
+
{{/relevantPeriod}}
|
15
|
+
{{^relevantPeriod}}
|
16
|
+
{{#authorDatetime}}
|
17
|
+
{{{author_effective_time}}}
|
18
|
+
{{/authorDatetime}}
|
19
|
+
{{/relevantPeriod}}
|
20
|
+
{{/resultDatetime}}
|
9
21
|
{{{result_value}}}
|
10
22
|
</observation>
|
11
23
|
</entryRelationship>
|
@@ -28,7 +28,7 @@ module Qrda
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def code_and_codesystem
|
31
|
-
oid = self['
|
31
|
+
oid = self['system'] || self['codeSystem']
|
32
32
|
if oid == '1.2.3.4.5.6.7.8.9.10'
|
33
33
|
"nullFlavor=\"NA\" sdtc:valueSet=\"#{self['code']}\""
|
34
34
|
else
|
@@ -37,7 +37,7 @@ module Qrda
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def primary_code_and_codesystem
|
40
|
-
oid = self[:dataElementCodes][0]['
|
40
|
+
oid = self[:dataElementCodes][0]['system'] || self[:dataElementCodes][0]['codeSystem']
|
41
41
|
"code=\"#{self[:dataElementCodes][0]['code']}\" codeSystem=\"#{oid}\" codeSystemName=\"#{HQMF::Util::CodeSystemHelper.code_system_for(oid)}\""
|
42
42
|
end
|
43
43
|
|
@@ -45,7 +45,7 @@ module Qrda
|
|
45
45
|
translation_list = ""
|
46
46
|
self[:dataElementCodes].each_with_index do |_dec, index|
|
47
47
|
next if index.zero?
|
48
|
-
oid = self[:dataElementCodes][index]['
|
48
|
+
oid = self[:dataElementCodes][index]['system'] || self[:dataElementCodes][index]['codeSystem']
|
49
49
|
translation_list += "<translation code=\"#{self[:dataElementCodes][index]['code']}\" codeSystem=\"#{oid}\" codeSystemName=\"#{HQMF::Util::CodeSystemHelper.code_system_for(oid)}\"/>"
|
50
50
|
end
|
51
51
|
translation_list
|
@@ -67,8 +67,6 @@ module Qrda
|
|
67
67
|
result_value_as_string(self['result'][0])
|
68
68
|
elsif self['result'].is_a? Hash
|
69
69
|
result_value_as_string(self['result'])
|
70
|
-
elsif self['result'].is_a? String
|
71
|
-
"<value xsi:type=\"ST\">#{self['result']}</value>"
|
72
70
|
elsif !self['result'].nil?
|
73
71
|
"<value xsi:type=\"PQ\" value=\"#{self['result']}\" unit=\"1\"/>"
|
74
72
|
end
|
@@ -77,7 +75,7 @@ module Qrda
|
|
77
75
|
|
78
76
|
def result_value_as_string(result)
|
79
77
|
return "<value xsi:type=\"CD\" nullFlavor=\"UNK\"/>" unless result
|
80
|
-
oid = result['
|
78
|
+
oid = result['system'] || result['codeSystem']
|
81
79
|
return "<value xsi:type=\"CD\" code=\"#{result['code']}\" codeSystem=\"#{oid}\" codeSystemName=\"#{HQMF::Util::CodeSystemHelper.code_system_for(oid)}\"/>" if result['code']
|
82
80
|
return "<value xsi:type=\"PQ\" value=\"#{result['value']}\" unit=\"#{result['unit']}\"/>" if result['unit']
|
83
81
|
end
|
@@ -83,6 +83,10 @@ module Qrda
|
|
83
83
|
"<effectiveTime #{value_or_null_flavor(self['relevantPeriod']['low'])}/>"
|
84
84
|
end
|
85
85
|
|
86
|
+
def relevant_date_time
|
87
|
+
"<effectiveTime #{value_or_null_flavor(self['relevantDatetime'])}/>"
|
88
|
+
end
|
89
|
+
|
86
90
|
def medication_duration_effective_time
|
87
91
|
"<effectiveTime xsi:type=\"IVL_TS\">"\
|
88
92
|
"<low #{value_or_null_flavor(self['relevantPeriod']['low'])}/>"\
|
@@ -9,23 +9,23 @@ module QRDA
|
|
9
9
|
patient.qdmPatient.birthDatetime = DateTime.parse(patient_element.at_xpath('cda:birthTime')['value'])
|
10
10
|
pcbd = QDM::PatientCharacteristicBirthdate.new
|
11
11
|
pcbd.birthDatetime = patient.qdmPatient.birthDatetime
|
12
|
-
pcbd.dataElementCodes = [{ code: '21112-8',
|
12
|
+
pcbd.dataElementCodes = [{ code: '21112-8', system: '2.16.840.1.113883.6.1' }]
|
13
13
|
patient.qdmPatient.dataElements << pcbd
|
14
14
|
|
15
15
|
pcs = QDM::PatientCharacteristicSex.new
|
16
16
|
code_element = patient_element.at_xpath('cda:administrativeGenderCode')
|
17
17
|
pcs.dataElementCodes = [code_if_present(code_element)]
|
18
|
-
patient.qdmPatient.dataElements << pcs
|
18
|
+
patient.qdmPatient.dataElements << pcs
|
19
19
|
|
20
20
|
pcr = QDM::PatientCharacteristicRace.new
|
21
21
|
code_element = patient_element.at_xpath('cda:raceCode')
|
22
22
|
pcr.dataElementCodes = [code_if_present(code_element)]
|
23
|
-
patient.qdmPatient.dataElements << pcr
|
23
|
+
patient.qdmPatient.dataElements << pcr
|
24
24
|
|
25
25
|
pce = QDM::PatientCharacteristicEthnicity.new
|
26
26
|
code_element = patient_element.at_xpath('cda:ethnicGroupCode')
|
27
27
|
pce.dataElementCodes = [code_if_present(code_element)]
|
28
|
-
patient.qdmPatient.dataElements << pce
|
28
|
+
patient.qdmPatient.dataElements << pce
|
29
29
|
end
|
30
30
|
|
31
31
|
def code_if_present(code_element)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module QRDA
|
2
2
|
module Cat1
|
3
3
|
class SectionImporter
|
4
|
-
attr_accessor :check_for_usable, :status_xpath, :code_xpath
|
4
|
+
attr_accessor :check_for_usable, :status_xpath, :code_xpath
|
5
5
|
|
6
6
|
def initialize(entry_finder)
|
7
7
|
@entry_finder = entry_finder
|
@@ -9,8 +9,6 @@ module QRDA
|
|
9
9
|
@entry_id_map = {}
|
10
10
|
@check_for_usable = true
|
11
11
|
@entry_class = QDM::DataElement
|
12
|
-
@warnings = []
|
13
|
-
@codes_modifiers = {}
|
14
12
|
end
|
15
13
|
|
16
14
|
# Traverses an HL7 CDA document passed in and creates an Array of Entry
|
@@ -43,7 +41,7 @@ module QRDA
|
|
43
41
|
# This is the id found in the QRDA file
|
44
42
|
entry_qrda_id = extract_id(entry_element, @id_xpath)
|
45
43
|
# Create a hash to map all of entry.ids to the same QRDA ids. This will be used to merge QRDA entries
|
46
|
-
# that represent the same event.
|
44
|
+
# that represent the same event.
|
47
45
|
@entry_id_map["#{entry_qrda_id.value}_#{entry_qrda_id.namingSystem}"] ||= []
|
48
46
|
@entry_id_map["#{entry_qrda_id.value}_#{entry_qrda_id.namingSystem}"] << entry.id
|
49
47
|
entry.dataElementCodes = extract_codes(entry_element, @code_xpath)
|
@@ -63,7 +61,7 @@ module QRDA
|
|
63
61
|
|
64
62
|
# If an extension is not included, use the root as the value. Other wise use the extension
|
65
63
|
value = id_element['extension'] || id_element['root']
|
66
|
-
identifier = QDM::
|
64
|
+
identifier = QDM::Identifier.new(value: value, namingSystem: id_element['root'])
|
67
65
|
identifier
|
68
66
|
end
|
69
67
|
|
@@ -92,53 +90,27 @@ module QRDA
|
|
92
90
|
end
|
93
91
|
|
94
92
|
def extract_interval(parent_element, interval_xpath)
|
95
|
-
# nil if the time interval does not exist
|
96
|
-
return nil unless time_interval_exists(parent_element, interval_xpath)
|
97
|
-
|
98
93
|
if parent_element.at_xpath("#{interval_xpath}/@value")
|
99
94
|
low_time = DateTime.parse(parent_element.at_xpath(interval_xpath)['value'])
|
100
95
|
high_time = DateTime.parse(parent_element.at_xpath(interval_xpath)['value'])
|
101
96
|
end
|
102
97
|
if parent_element.at_xpath("#{interval_xpath}/cda:low")
|
103
|
-
low_time =
|
104
|
-
DateTime.parse(parent_element.at_xpath("#{interval_xpath}/cda:low")['value'])
|
105
|
-
end
|
98
|
+
low_time = DateTime.parse(parent_element.at_xpath("#{interval_xpath}/cda:low")['value'])
|
106
99
|
end
|
107
100
|
if parent_element.at_xpath("#{interval_xpath}/cda:high")
|
108
101
|
high_time = if parent_element.at_xpath("#{interval_xpath}/cda:high")['value']
|
109
102
|
DateTime.parse(parent_element.at_xpath("#{interval_xpath}/cda:high")['value'])
|
103
|
+
else
|
104
|
+
DateTime.new(9999,1,1)
|
110
105
|
end
|
111
106
|
end
|
112
107
|
if parent_element.at_xpath("#{interval_xpath}/cda:center")
|
113
108
|
low_time = Time.parse(parent_element.at_xpath("#{interval_xpath}/cda:center")['value'])
|
114
109
|
high_time = Time.parse(parent_element.at_xpath("#{interval_xpath}/cda:center")['value'])
|
115
110
|
end
|
116
|
-
if low_time && high_time && low_time > high_time
|
117
|
-
# pass warning: current code continues as expected, but adds warning
|
118
|
-
id_attr = parent_element.at_xpath(".//cda:id")&.attributes
|
119
|
-
id_str = id_attr ? "and id: #{id_attr['root']&.value}(root), #{id_attr['extension']&.value}(extension)" : ""
|
120
|
-
qrda_type = @entry_class.to_s.split("::")[1]
|
121
|
-
@warnings << ValidationError.new(message: "Interval with low time after high time. Located in element with QRDA type: #{qrda_type} #{id_str}",
|
122
|
-
location: parent_element.path)
|
123
|
-
end
|
124
|
-
if low_time.nil? && high_time.nil?
|
125
|
-
id_attr = parent_element.at_xpath(".//cda:id")&.attributes
|
126
|
-
id_str = id_attr ? "and id: #{id_attr['root']&.value}(root), #{id_attr['extension']&.value}(extension)" : ""
|
127
|
-
qrda_type = @entry_class.to_s.split("::")[1]
|
128
|
-
@warnings << ValidationError.new(message: "Interval with nullFlavor low time and nullFlavor high time. Located in element with QRDA type: #{qrda_type} #{id_str}",
|
129
|
-
location: parent_element.path)
|
130
|
-
end
|
131
111
|
QDM::Interval.new(low_time, high_time).shift_dates(0)
|
132
112
|
end
|
133
113
|
|
134
|
-
def time_interval_exists(parent_element, interval_xpath)
|
135
|
-
# false if the time interval does not exist
|
136
|
-
return false unless parent_element.at_xpath(interval_xpath)
|
137
|
-
# false if the time element exists but has a null Flavor
|
138
|
-
return false if parent_element.at_xpath(interval_xpath)['nullFlavor']
|
139
|
-
true
|
140
|
-
end
|
141
|
-
|
142
114
|
def extract_time(parent_element, datetime_xpath)
|
143
115
|
DateTime.parse(parent_element.at_xpath(datetime_xpath)['value']) if parent_element.at_xpath("#{datetime_xpath}/@value")
|
144
116
|
end
|
@@ -178,11 +150,12 @@ module QRDA
|
|
178
150
|
parent_element.xpath(@result_xpath).each do |elem|
|
179
151
|
result << extract_result_value(elem)
|
180
152
|
end
|
181
|
-
result.size > 1 ? result : result.first
|
153
|
+
result.size > 1 ? result : result.first
|
182
154
|
end
|
183
155
|
|
184
156
|
def extract_result_value(value_element)
|
185
157
|
return unless value_element && !value_element['nullFlavor']
|
158
|
+
|
186
159
|
value = value_element['value']
|
187
160
|
if value.present?
|
188
161
|
return value.strip.to_f if (value_element['unit'] == "1" || value_element['unit'].nil?)
|
@@ -190,13 +163,6 @@ module QRDA
|
|
190
163
|
return QDM::Quantity.new(value.strip.to_f, value_element['unit'])
|
191
164
|
elsif value_element['code'].present?
|
192
165
|
return code_if_present(value_element)
|
193
|
-
elsif value_element.text.present?
|
194
|
-
id_attr = value_element.parent.at_xpath(".//cda:id")&.attributes
|
195
|
-
id_str = id_attr ? "and id: #{id_attr['root']&.value}(root), #{id_attr['extension']&.value}(extension)" : ""
|
196
|
-
qrda_type = @entry_class.to_s.split("::")[1]
|
197
|
-
@warnings << ValidationError.new(message: "Value with string type found. When possible, it's best practice to use a coded value or scalar. Located in element with QRDA type: #{qrda_type} #{id_str}",
|
198
|
-
location: value_element.path)
|
199
|
-
return value_element.text
|
200
166
|
end
|
201
167
|
end
|
202
168
|
|
@@ -206,16 +172,16 @@ module QRDA
|
|
206
172
|
negation_indicator = parent_element['negationInd']
|
207
173
|
# Return and do not set reason attribute if the entry is negated
|
208
174
|
return nil if negation_indicator.eql?('true')
|
209
|
-
|
210
|
-
reason_element.blank? ? nil : code_if_present(reason_element.first)
|
175
|
+
|
176
|
+
reason_element.blank? ? nil : code_if_present(reason_element.first)
|
211
177
|
end
|
212
178
|
|
213
179
|
def extract_negation(parent_element, entry)
|
214
180
|
negation_element = parent_element.xpath("./cda:entryRelationship[@typeCode='RSON']/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.88']/cda:value")
|
215
181
|
negation_indicator = parent_element['negationInd']
|
216
182
|
# Return and do not set negationRationale attribute if the entry is not negated
|
217
|
-
return unless negation_indicator.eql?('true')
|
218
|
-
|
183
|
+
return unless negation_indicator.eql?('true')
|
184
|
+
|
219
185
|
entry.negationRationale = code_if_present(negation_element.first) unless negation_element.blank?
|
220
186
|
extract_negated_code(parent_element, entry)
|
221
187
|
end
|
@@ -223,18 +189,8 @@ module QRDA
|
|
223
189
|
def extract_negated_code(parent_element, entry)
|
224
190
|
code_elements = parent_element.xpath(@code_xpath)
|
225
191
|
code_elements.each do |code_element|
|
226
|
-
if code_element['nullFlavor'] == 'NA'
|
227
|
-
|
228
|
-
entry.dataElementCodes = [{ code: code_element['sdtc:valueSet'], codeSystemOid: '1.2.3.4.5.6.7.8.9.10' }]
|
229
|
-
else
|
230
|
-
# negated code is nullFlavored with no valueset
|
231
|
-
entry.dataElementCodes = [{ code: "NA", codeSystemOid: '1.2.3.4.5.6.7.8.9.10' }]
|
232
|
-
id_attr = parent_element.at_xpath(".//cda:id")&.attributes
|
233
|
-
id_str = id_attr ? "and id: #{id_attr['root']&.value}(root), #{id_attr['extension']&.value}(extension)" : ""
|
234
|
-
qrda_type = @entry_class.to_s.split("::")[1]
|
235
|
-
@warnings << ValidationError.new(message: "Negated code element contains nullFlavor code but no valueset. Located in element with QRDA type: #{qrda_type} #{id_str}.",
|
236
|
-
location: parent_element.path)
|
237
|
-
end
|
192
|
+
if code_element['nullFlavor'] == 'NA' && code_element['sdtc:valueSet']
|
193
|
+
entry.dataElementCodes = [{ code: code_element['sdtc:valueSet'], system: '1.2.3.4.5.6.7.8.9.10' }]
|
238
194
|
end
|
239
195
|
end
|
240
196
|
end
|
@@ -6,7 +6,7 @@ module QRDA
|
|
6
6
|
@id_xpath = './cda:id'
|
7
7
|
@code_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.148']/cda:value"
|
8
8
|
@author_datetime_xpath = './cda:author/cda:time'
|
9
|
-
@
|
9
|
+
@relevant_date_time_xpath = './cda:effectiveTime'
|
10
10
|
@facility_locations_xpath = "./cda:participant[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.100']"
|
11
11
|
@severity_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.22.4.8']/cda:value"
|
12
12
|
@type_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.22.4.9']/cda:value"
|
@@ -6,7 +6,7 @@ module QRDA
|
|
6
6
|
@id_xpath = './cda:id'
|
7
7
|
@code_xpath = "./cda:entryRelationship[@typeCode='REFR']/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.88']/cda:value"
|
8
8
|
@author_datetime_xpath = "./cda:author/cda:time"
|
9
|
-
@relevant_period_xpath = "./cda:effectiveTime"
|
9
|
+
# @relevant_period_xpath = "./cda:effectiveTime"
|
10
10
|
@related_to_xpath = "./sdtc:inFulfillmentOf1/sdtc:actReference"
|
11
11
|
@category_xpath = './cda:code'
|
12
12
|
@medium_xpath = "./cda:participant[@typeCode='VIA']/cda:participantRole/cda:code"
|
@@ -19,9 +19,9 @@ module QRDA
|
|
19
19
|
communication_performed = super
|
20
20
|
communication_performed.category = code_if_present(entry_element.at_xpath(@category_xpath))
|
21
21
|
communication_performed.medium = code_if_present(entry_element.at_xpath(@medium_xpath))
|
22
|
-
communication_performed.sender = code_if_present(entry_element.at_xpath(@sender_xpath))
|
23
|
-
communication_performed.recipient = code_if_present(entry_element.at_xpath(@recipient_xpath))
|
24
|
-
communication_performed.relatedTo = extract_related_to(entry_element)
|
22
|
+
# communication_performed.sender = code_if_present(entry_element.at_xpath(@sender_xpath))
|
23
|
+
# communication_performed.recipient = code_if_present(entry_element.at_xpath(@recipient_xpath))
|
24
|
+
# communication_performed.relatedTo = extract_related_to(entry_element)
|
25
25
|
communication_performed
|
26
26
|
end
|
27
27
|
end
|
@@ -20,7 +20,7 @@ module QRDA
|
|
20
20
|
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
21
21
|
diagnostic_study_performed = super
|
22
22
|
diagnostic_study_performed.resultDatetime = extract_time(entry_element, @result_datetime_xpath)
|
23
|
-
diagnostic_study_performed.resultDatetime ||= extract_interval(entry_element, @result_datetime_xpath)
|
23
|
+
diagnostic_study_performed.resultDatetime ||= extract_interval(entry_element, @result_datetime_xpath).low
|
24
24
|
diagnostic_study_performed.status = code_if_present(entry_element.at_xpath(@status_xpath))
|
25
25
|
diagnostic_study_performed.method = code_if_present(entry_element.at_xpath(@method_xpath))
|
26
26
|
diagnostic_study_performed.facilityLocation = extract_facility_locations(entry_element)[0]
|
@@ -10,7 +10,6 @@ module QRDA
|
|
10
10
|
@admission_source_xpath = "./cda:entryRelationship/cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.23']/cda:participant/cda:participantRole[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.151']/cda:code"
|
11
11
|
@discharge_disposition_xpath = "./cda:entryRelationship/cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.23']/sdtc:dischargeDispositionCode"
|
12
12
|
@facility_locations_xpath = "./cda:entryRelationship/cda:encounter/cda:participant[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.100']"
|
13
|
-
@principal_diagnosis_xpath = "./cda:entryRelationship/cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.23']/cda:entryRelationship/cda:observation[cda:code/@code='8319008']/cda:value"
|
14
13
|
@diagnosis_xpath = "./cda:entryRelationship/cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.23']/cda:entryRelationship/cda:act/cda:entryRelationship/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.22.4.4']"
|
15
14
|
@entry_class = QDM::EncounterPerformed
|
16
15
|
end
|
@@ -20,27 +19,16 @@ module QRDA
|
|
20
19
|
encounter_performed.admissionSource = code_if_present(entry_element.at_xpath(@admission_source_xpath))
|
21
20
|
encounter_performed.dischargeDisposition = code_if_present(entry_element.at_xpath(@discharge_disposition_xpath))
|
22
21
|
encounter_performed.facilityLocations = extract_facility_locations(entry_element)
|
23
|
-
encounter_performed.principalDiagnosis = code_if_present(entry_element.at_xpath(@principal_diagnosis_xpath))
|
24
22
|
encounter_performed.diagnoses = extract_diagnoses(entry_element)
|
25
23
|
if encounter_performed&.relevantPeriod&.low && encounter_performed&.relevantPeriod&.high
|
26
24
|
los = encounter_performed.relevantPeriod.high - encounter_performed.relevantPeriod.low
|
27
25
|
encounter_performed.lengthOfStay = QDM::Quantity.new(los.to_i, 'd')
|
28
26
|
end
|
29
|
-
extract_modifier_code(encounter_performed, entry_element)
|
30
27
|
encounter_performed
|
31
28
|
end
|
32
29
|
|
33
30
|
private
|
34
31
|
|
35
|
-
def extract_modifier_code(encounter_performed, entry_element)
|
36
|
-
code_element = entry_element.at_xpath(@code_xpath)
|
37
|
-
return unless code_element
|
38
|
-
|
39
|
-
qualifier_name = code_element.at_xpath('./cda:qualifier/cda:name')
|
40
|
-
qualifier_value = code_element.at_xpath('./cda:qualifier/cda:value')
|
41
|
-
codes_modifiers[encounter_performed.id] = { name: code_if_present(qualifier_name), value: code_if_present(qualifier_value), xpath_location: entry_element.path } if qualifier_value || qualifier_name
|
42
|
-
end
|
43
|
-
|
44
32
|
def extract_diagnoses(parent_element)
|
45
33
|
diagnosis_elements = parent_element.xpath(@diagnosis_xpath)
|
46
34
|
diagnosis_list = []
|
@@ -16,7 +16,7 @@ module QRDA
|
|
16
16
|
|
17
17
|
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
18
18
|
immunization_order = super
|
19
|
-
immunization_order.activeDatetime = extract_interval(entry_element, @active_datetime_xpath)
|
19
|
+
immunization_order.activeDatetime = extract_interval(entry_element, @active_datetime_xpath).low
|
20
20
|
immunization_order.dosage = extract_scalar(entry_element, @dosage_xpath)
|
21
21
|
immunization_order.supply = extract_scalar(entry_element, @supply_xpath)
|
22
22
|
immunization_order.route = code_if_present(entry_element.at_xpath(@route_xpath))
|
@@ -26,8 +26,8 @@ module QRDA
|
|
26
26
|
medication_dispensed.frequency = frequency_as_coded_value(entry_element, @frequency_xpath)
|
27
27
|
medication_dispensed.daysSupplied = extract_scalar(entry_element, @days_supplied_xpath)&.value
|
28
28
|
medication_dispensed.route = code_if_present(entry_element.at_xpath(@route_xpath))
|
29
|
-
medication_dispensed.prescriberId = extract_id(entry_element, @prescriber_id_xpath)
|
30
|
-
medication_dispensed.dispenserId = extract_id(entry_element, @dispenser_id_xpath)
|
29
|
+
# medication_dispensed.prescriberId = extract_id(entry_element, @prescriber_id_xpath)
|
30
|
+
# medication_dispensed.dispenserId = extract_id(entry_element, @dispenser_id_xpath)
|
31
31
|
medication_dispensed
|
32
32
|
end
|
33
33
|
|
@@ -27,7 +27,7 @@ module QRDA
|
|
27
27
|
medication_order.refills = extract_scalar(entry_element, @refills_xpath)&.value
|
28
28
|
medication_order.route = code_if_present(entry_element.at_xpath(@route_xpath))
|
29
29
|
medication_order.setting = code_if_present(entry_element.at_xpath(@setting_xpath))
|
30
|
-
medication_order.prescriberId = extract_id(entry_element, @prescriber_id_xpath)
|
30
|
+
# medication_order.prescriberId = extract_id(entry_element, @prescriber_id_xpath)
|
31
31
|
medication_order.daysSupplied = extract_scalar(entry_element, @days_supplied_xpath)&.value
|
32
32
|
medication_order.reason = extract_reason(entry_element)
|
33
33
|
medication_order
|
@@ -7,7 +7,6 @@ module QRDA
|
|
7
7
|
@code_xpath = './cda:code'
|
8
8
|
@author_datetime_xpath = "./cda:author/cda:time"
|
9
9
|
@anatomical_location_site_xpath = "./cda:targetSiteCode"
|
10
|
-
@ordinality_xpath = "./cda:priorityCode"
|
11
10
|
@reason_xpath = "./cda:entryRelationship[@typeCode='RSON']/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.88']/cda:value"
|
12
11
|
@entry_class = QDM::ProcedureOrder
|
13
12
|
end
|
@@ -15,7 +14,6 @@ module QRDA
|
|
15
14
|
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
16
15
|
procedure_order = super
|
17
16
|
procedure_order.anatomicalLocationSite = code_if_present(entry_element.at_xpath(@anatomical_location_site_xpath))
|
18
|
-
procedure_order.ordinality = code_if_present(entry_element.at_xpath(@ordinality_xpath))
|
19
17
|
procedure_order.reason = extract_reason(entry_element)
|
20
18
|
procedure_order
|
21
19
|
end
|
@@ -11,7 +11,6 @@ module QRDA
|
|
11
11
|
@result_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.22.4.2']/cda:value"
|
12
12
|
@status_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.93']/cda:value"
|
13
13
|
@anatomical_location_site_xpath = "./cda:targetSiteCode"
|
14
|
-
@ordinality_xpath = "./cda:priorityCode"
|
15
14
|
@incision_datetime_xpath = "./cda:entryRelationship/cda:procedure[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.89']/cda:effectiveTime"
|
16
15
|
@components_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.149']"
|
17
16
|
@reason_xpath = "./cda:entryRelationship[@typeCode='RSON']/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.88']/cda:value"
|
@@ -23,7 +22,6 @@ module QRDA
|
|
23
22
|
procedure_performed.method = code_if_present(entry_element.at_xpath(@method_xpath))
|
24
23
|
procedure_performed.status = code_if_present(entry_element.at_xpath(@status_xpath))
|
25
24
|
procedure_performed.anatomicalLocationSite = code_if_present(entry_element.at_xpath(@anatomical_location_site_xpath))
|
26
|
-
procedure_performed.ordinality = code_if_present(entry_element.at_xpath(@ordinality_xpath))
|
27
25
|
procedure_performed.incisionDatetime = extract_time(entry_element, @incision_datetime_xpath)
|
28
26
|
procedure_performed.components = extract_components(entry_element)
|
29
27
|
procedure_performed.reason = extract_reason(entry_element)
|