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.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -2
  3. data/README.md +0 -27
  4. data/lib/{cqm_report.rb → cqm-reports.rb} +4 -2
  5. data/lib/ext/code.rb +11 -0
  6. data/lib/ext/data_element.rb +24 -0
  7. data/lib/html-export/qdm-patient/qdm_patient.rb +3 -3
  8. data/lib/qrda-export/catI-r5/_header.mustache +2 -2
  9. data/lib/qrda-export/catI-r5/qrda1_r5.mustache +2 -6
  10. data/lib/qrda-export/catI-r5/qrda1_r5.rb +2 -28
  11. data/lib/qrda-export/catI-r5/qrda_header/_record_target.mustache +11 -24
  12. data/lib/qrda-export/catI-r5/qrda_templates/adverse_event.mustache +4 -4
  13. data/lib/qrda-export/catI-r5/qrda_templates/allergy_intolerance.mustache +6 -1
  14. data/lib/qrda-export/catI-r5/qrda_templates/communication_performed.mustache +2 -2
  15. data/lib/qrda-export/catI-r5/qrda_templates/diagnosis.mustache +6 -1
  16. data/lib/qrda-export/catI-r5/qrda_templates/encounter_performed.mustache +0 -4
  17. data/lib/qrda-export/catI-r5/qrda_templates/immunization_administered.mustache +2 -7
  18. data/lib/qrda-export/catI-r5/qrda_templates/medication_discharge.mustache +2 -0
  19. data/lib/qrda-export/catI-r5/qrda_templates/procedure_order.mustache +0 -4
  20. data/lib/qrda-export/catI-r5/qrda_templates/procedure_performed.mustache +0 -4
  21. data/lib/qrda-export/catI-r5/qrda_templates/procedure_recommended.mustache +0 -4
  22. data/lib/qrda-export/catI-r5/qrda_templates/substance_recommended.mustache +0 -1
  23. data/lib/qrda-export/catI-r5/qrda_templates/symptom.mustache +6 -1
  24. data/lib/qrda-export/catI-r5/qrda_templates/template_partials/_encounter_diagnosis.mustache +3 -1
  25. data/lib/qrda-export/catI-r5/qrda_templates/template_partials/_medication_supply_request.mustache +1 -1
  26. data/lib/qrda-export/catI-r5/qrda_templates/template_partials/_results.mustache +12 -0
  27. data/lib/qrda-export/helper/cat1_view_helper.rb +4 -6
  28. data/lib/qrda-export/helper/date_helper.rb +4 -0
  29. data/lib/qrda-import/base-importers/demographics_importer.rb +4 -4
  30. data/lib/qrda-import/base-importers/section_importer.rb +14 -58
  31. data/lib/qrda-import/data-element-importers/adverse_event_importer.rb +1 -1
  32. data/lib/qrda-import/data-element-importers/communication_performed_importer.rb +4 -4
  33. data/lib/qrda-import/data-element-importers/diagnostic_study_performed_importer.rb +1 -1
  34. data/lib/qrda-import/data-element-importers/encounter_performed_importer.rb +0 -12
  35. data/lib/qrda-import/data-element-importers/immunization_order_importer.rb +1 -1
  36. data/lib/qrda-import/data-element-importers/medication_dispensed_importer.rb +2 -2
  37. data/lib/qrda-import/data-element-importers/medication_order_importer.rb +1 -1
  38. data/lib/qrda-import/data-element-importers/procedure_order_importer.rb +0 -2
  39. data/lib/qrda-import/data-element-importers/procedure_performed_importer.rb +0 -2
  40. data/lib/qrda-import/data-element-importers/procedure_recommended_importer.rb +0 -2
  41. data/lib/qrda-import/entry_package.rb +16 -0
  42. data/lib/qrda-import/patient_importer.rb +62 -85
  43. metadata +15 -29
  44. data/lib/qrda-export/catI-r5/qrda_templates/provider_characteristic.mustache +0 -15
  45. 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}}
@@ -14,7 +14,9 @@
14
14
  {{#relevantPeriod}}
15
15
  {{{relevant_period}}}
16
16
  {{/relevantPeriod}}
17
- <value {{> _code}} xsi:type="CD"/>
17
+ {{#code}}
18
+ <value {{> _code}} xsi:type="CD"/>
19
+ {{/code}}
18
20
  </observation>
19
21
  </entryRelationship>
20
22
  </act>
@@ -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="2015-04-05"/>
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['codeSystemOid'] || self['codeSystem']
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]['codeSystemOid'] || self[:dataElementCodes][0]['codeSystem']
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]['codeSystemOid'] || self[:dataElementCodes][index]['codeSystem']
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['codeSystemOid'] || result['codeSystem']
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', codeSystemOid: '2.16.840.1.113883.6.1' }]
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 unless pcs.dataElementCodes.compact.blank?
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 unless pcr.dataElementCodes.compact.blank?
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 unless pce.dataElementCodes.compact.blank?
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, :warnings, :codes_modifiers
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::Id.new(value: value, namingSystem: id_element['root'])
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 = if parent_element.at_xpath("#{interval_xpath}/cda:low")['value']
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
- if code_element['sdtc:valueSet']
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
- @relevant_period_xpath = './cda:effectiveTime'
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)&.low
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)&.low
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)