cqm-reports 4.0.1 → 4.1.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.
- checksums.yaml +4 -4
- data/Gemfile +0 -2
- data/lib/html-export/qdm-patient/data_element/_data_element_other_fields.mustache +1 -1
- data/lib/html-export/qdm-patient/qdm_patient.rb +22 -5
- data/lib/qrda-export/catI-r5/qrda1_r5.rb +12 -0
- data/lib/qrda-export/catI-r5/qrda_header/_participant.mustache +3 -2
- data/lib/qrda-export/catI-r5/qrda_header/_record_target.mustache +9 -0
- data/lib/qrda-export/catI-r5/qrda_templates/encounter_performed.mustache +49 -56
- data/lib/qrda-export/catI-r5/qrda_templates/medication_discharge.mustache +1 -1
- data/lib/qrda-export/catI-r5/qrda_templates/medication_dispensed.mustache +1 -1
- data/lib/qrda-export/catI-r5/qrda_templates/medication_order.mustache +1 -1
- data/lib/qrda-export/catI-r5/qrda_templates/template_partials/_medication_details.mustache +1 -1
- data/lib/qrda-export/catI-r52/qrda1_r52.rb +258 -0
- data/lib/qrda-export/catI-r52/qrda_header/_participant.mustache +8 -0
- data/lib/qrda-export/catI-r52/qrda_header/_record_target.mustache +65 -0
- data/lib/qrda-export/catI-r52/qrda_templates/medication_order.mustache +70 -0
- data/lib/qrda-export/catIII/_header.mustache +2 -4
- data/lib/qrda-export/catIII/qrda_header/_participant_ehr.mustache +4 -1
- data/lib/qrda-export/catIII-r2-1/qrda_header/_participant_ehr.mustache +9 -0
- data/lib/qrda-export/helper/cat1_view_helper.rb +23 -5
- data/lib/qrda-export/helper/view_helper.rb +9 -1
- data/lib/qrda-import/base-importers/section_importer.rb +31 -4
- data/lib/qrda-import/data-element-importers/encounter_performed_importer.rb +12 -12
- data/lib/qrda-import/data-element-importers/medication_discharge_importer.rb +1 -1
- data/lib/qrda-import/data-element-importers/medication_dispensed_importer.rb +1 -1
- data/lib/qrda-import/data-element-importers/medication_order_importer.rb +1 -1
- data/lib/qrda-import/data-element-importers/substance_order_importer.rb +1 -1
- data/lib/qrda-import/data-element-importers/substance_recommended_importer.rb +1 -1
- data/lib/qrda-import/patient_importer.rb +22 -6
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0938369271d07282db5933dda15b47f0cbe346abbeff4a6004a23fcce61e680
|
4
|
+
data.tar.gz: 4ff25f7dfda32510cccb638966ab51eb76cb04c7ab31778fb2e95bc0cba88a2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c3c6bd90513f5f83610596a4789a30b0995569efcf7e6598a48f385a00d7cc869265c4f7f6b77c24c3130153df714ad3858d55e4b97f88168282d833e4a2961
|
7
|
+
data.tar.gz: 750f9df81d0cb2c633dbecc2b6be45a77c580dd7bc53defe6cc27ad592e0588cbebd563f3382e7d193f2cfcdf038728f3e01eee1f9fdbb2fc07e3a11f049afdb
|
data/Gemfile
CHANGED
@@ -49,7 +49,7 @@
|
|
49
49
|
{{/daysSupplied}}
|
50
50
|
{{#diagnoses}}
|
51
51
|
<div class="div-head-row">
|
52
|
-
<div class="div-table-head--no-border"><span class="criteria-heading">Diagnosis{{{
|
52
|
+
<div class="div-table-head--no-border"><span class="criteria-heading">Diagnosis:</span> {{{nested_code_string}}} {{{diagnosis_string}}}</div>
|
53
53
|
</div>
|
54
54
|
{{/diagnoses}}
|
55
55
|
{{#dischargeDisposition}}
|
@@ -10,6 +10,7 @@ class QdmPatient < Mustache
|
|
10
10
|
@patient = patient
|
11
11
|
@qdmPatient = patient.qdmPatient
|
12
12
|
@patient_addresses = patient['addresses']
|
13
|
+
@patient_email = patient['email']
|
13
14
|
@patient_telecoms = patient['telecoms']
|
14
15
|
end
|
15
16
|
|
@@ -35,6 +36,7 @@ class QdmPatient < Mustache
|
|
35
36
|
def patient_telecoms
|
36
37
|
@patient_telecoms ||= [CQM::Telecom.new(use: 'HP', value: '555-555-2003')]
|
37
38
|
# create formatted telecoms
|
39
|
+
@patient_telecoms << CQM::Telecom.new(use: 'HP', value: @patient_email) if @patient_email
|
38
40
|
@patient_telecoms.map { |telecom| "(#{telecom['use']}) #{telecom['value']}" }.join("<br>")
|
39
41
|
end
|
40
42
|
|
@@ -52,8 +54,14 @@ class QdmPatient < Mustache
|
|
52
54
|
end
|
53
55
|
|
54
56
|
def unit_string
|
55
|
-
return
|
56
|
-
"#{self['value']} #{self['unit']}"
|
57
|
+
return trimed_value(self['value']).to_s if !self['unit'] || self['unit'] == '1'
|
58
|
+
"#{trimed_value(self['value'])} #{self['unit']}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def trimed_value(number)
|
62
|
+
i = number.to_i
|
63
|
+
f = number.to_f
|
64
|
+
i == f ? i : f
|
57
65
|
end
|
58
66
|
|
59
67
|
def entity_string
|
@@ -120,15 +128,24 @@ class QdmPatient < Mustache
|
|
120
128
|
return unit_string if self['value']
|
121
129
|
return code_code_system_string if self['code']
|
122
130
|
|
123
|
-
|
131
|
+
# Checks to see if the result is a DateTime value, String, or Numeric
|
132
|
+
begin
|
133
|
+
DateTime.parse(self['result'])
|
134
|
+
rescue ArgumentError, TypeError
|
135
|
+
# If the value is not numeric, just print out the result
|
136
|
+
self['result'].is_a?(Numeric) ? trimed_value(self['result']) : self['result']
|
137
|
+
end
|
124
138
|
end
|
125
139
|
|
126
140
|
def nested_code_string
|
127
141
|
code_for_element(self['code'])
|
128
142
|
end
|
129
143
|
|
130
|
-
def
|
131
|
-
|
144
|
+
def diagnosis_string
|
145
|
+
dx_string = ''
|
146
|
+
dx_string += "</br> rank: #{self['rank']}" if self['rank']
|
147
|
+
dx_string += "</br> presentOnAdmissionIndicator: #{self['presentOnAdmissionIndicator']['code']}" if self['presentOnAdmissionIndicator']
|
148
|
+
dx_string
|
132
149
|
end
|
133
150
|
|
134
151
|
def end_time?
|
@@ -16,9 +16,12 @@ class Qrda1R5 < Mustache
|
|
16
16
|
@provider = options[:provider]
|
17
17
|
@patient_address_option = options[:patient_addresses]
|
18
18
|
@patient_telecom_option = options[:patient_telecoms]
|
19
|
+
@patient_email_option = options[:patient_email]
|
19
20
|
@performance_period_start = options[:start_time]
|
20
21
|
@performance_period_end = options[:end_time]
|
21
22
|
@submission_program = options[:submission_program]
|
23
|
+
@medicare_beneficiary_identifier = options[:medicare_beneficiary_identifier]
|
24
|
+
@hicn = options[:hicn]
|
22
25
|
end
|
23
26
|
|
24
27
|
def patient_addresses
|
@@ -41,6 +44,15 @@ class Qrda1R5 < Mustache
|
|
41
44
|
JSON.parse(@patient_telecom_option.to_json)
|
42
45
|
end
|
43
46
|
|
47
|
+
def patient_email
|
48
|
+
return unless @patient_email_option
|
49
|
+
telecom_email = [CQM::Telecom.new(
|
50
|
+
use: 'HP',
|
51
|
+
value: @patient_email_option
|
52
|
+
)]
|
53
|
+
JSON.parse(telecom_email.to_json)
|
54
|
+
end
|
55
|
+
|
44
56
|
def patient_characteristic_payer
|
45
57
|
JSON.parse(@qdmPatient.get_data_elements('patient_characteristic', 'payer').to_json)
|
46
58
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
<participant typeCode="DEV">
|
2
2
|
<associatedEntity classCode="RGPR">
|
3
3
|
<!-- CMS EHR Certification Number (formerly known as Office of the
|
4
|
-
National Coordinator Certification Number)
|
5
|
-
|
4
|
+
National Coordinator Certification Number). Note, this is a test
|
5
|
+
file, and the provided ID is not for a certified product set. -->
|
6
|
+
<id extension="0015CPV4ZTB4WBU" root="2.16.840.1.113883.3.2074.1"/>
|
6
7
|
</associatedEntity>
|
7
8
|
</participant>
|
@@ -1,6 +1,12 @@
|
|
1
1
|
<recordTarget>
|
2
2
|
<patientRole>
|
3
3
|
<id extension="{{mrn}}" root="1.3.6.1.4.1.115" />
|
4
|
+
{{#medicare_beneficiary_identifier}}
|
5
|
+
<id extension="{{medicare_beneficiary_identifier}}" root="2.16.840.1.113883.4.927" />
|
6
|
+
{{/medicare_beneficiary_identifier}}
|
7
|
+
{{#hicn}}
|
8
|
+
<id extension="{{hicn}}" root="2.16.840.1.113883.4.572" />
|
9
|
+
{{/hicn}}
|
4
10
|
{{#patient_addresses}}
|
5
11
|
<addr use="{{use}}">
|
6
12
|
{{#street}}
|
@@ -15,6 +21,9 @@
|
|
15
21
|
{{#patient_telecoms}}
|
16
22
|
<telecom use="{{use}}" value="tel:{{value}}"/>
|
17
23
|
{{/patient_telecoms}}
|
24
|
+
{{#patient_email}}
|
25
|
+
<telecom use="{{use}}" value="mailto:{{value}}"/>
|
26
|
+
{{/patient_email}}
|
18
27
|
<patient>
|
19
28
|
{{#patient}}
|
20
29
|
<name>
|
@@ -1,58 +1,51 @@
|
|
1
1
|
<entry>
|
2
|
-
<
|
3
|
-
<!--Encounter
|
4
|
-
<templateId extension="
|
5
|
-
|
6
|
-
<
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
{{#relatedTo}}
|
52
|
-
<!-- QDM Attribute: relatedTo -->
|
53
|
-
{{> qrda_templates/template_partials/_related_to}}
|
54
|
-
{{/relatedTo}}
|
55
|
-
</encounter>
|
56
|
-
</entryRelationship>
|
57
|
-
</act>
|
2
|
+
<encounter classCode="ENC" moodCode="EVN">
|
3
|
+
<!-- Encounter activities template -->
|
4
|
+
<templateId extension="2015-08-01" root="2.16.840.1.113883.10.20.22.4.49"/>
|
5
|
+
<!-- Encounter performed template -->
|
6
|
+
<templateId extension="2021-08-01" root="2.16.840.1.113883.10.20.24.3.23"/>
|
7
|
+
<id extension="{{object_id}}" root="1.3.6.1.4.1.115"/>
|
8
|
+
<!-- QDM Attribute: Code -->
|
9
|
+
{{> _codes}}
|
10
|
+
<text>{{description}}</text>
|
11
|
+
<statusCode code="completed"/>
|
12
|
+
{{#relevantPeriod}}
|
13
|
+
<!-- QDM Attribute: Relevant Period -->
|
14
|
+
{{{relevant_period}}}
|
15
|
+
{{/relevantPeriod}}
|
16
|
+
{{#dischargeDisposition}}
|
17
|
+
<!-- QDM Attribute: Discharge Disposition -->
|
18
|
+
<sdtc:dischargeDispositionCode {{> _code}}/>
|
19
|
+
{{/dischargeDisposition}}
|
20
|
+
{{#authorDatetime}}
|
21
|
+
<!-- QDM Attribute: Author dateTime -->
|
22
|
+
{{> qrda_templates/template_partials/_author}}
|
23
|
+
{{/authorDatetime}}
|
24
|
+
{{#facilityLocations}}
|
25
|
+
<!-- QDM Attribute: Facility Locations -->
|
26
|
+
{{> qrda_templates/template_partials/_facility_location}}
|
27
|
+
{{/facilityLocations}}
|
28
|
+
{{#admissionSource}}
|
29
|
+
<!-- QDM Attribute: Admission Source -->
|
30
|
+
{{> qrda_templates/template_partials/_admission_source}}
|
31
|
+
{{/admissionSource}}
|
32
|
+
{{#participant}}
|
33
|
+
<!-- QDM Attribute: Participant -->
|
34
|
+
<participant typeCode="PRF">
|
35
|
+
{{> qrda_templates/template_partials/_entity}}
|
36
|
+
</participant>
|
37
|
+
{{/participant}}
|
38
|
+
{{#clazz}}
|
39
|
+
<!-- QDM Attribute: Class -->
|
40
|
+
{{> qrda_templates/template_partials/_encounter_class}}
|
41
|
+
{{/clazz}}
|
42
|
+
{{#diagnoses}}
|
43
|
+
<!-- QDM Attribute: Diagnoses -->
|
44
|
+
{{> qrda_templates/template_partials/_encounter_diagnosis_qdm}}
|
45
|
+
{{/diagnoses}}
|
46
|
+
{{#relatedTo}}
|
47
|
+
<!-- QDM Attribute: relatedTo -->
|
48
|
+
{{> qrda_templates/template_partials/_related_to}}
|
49
|
+
{{/relatedTo}}
|
50
|
+
</encounter>
|
58
51
|
</entry>
|
@@ -0,0 +1,258 @@
|
|
1
|
+
require 'mustache'
|
2
|
+
class Qrda1R52 < Mustache
|
3
|
+
include Qrda::Export::Helper::DateHelper
|
4
|
+
include Qrda::Export::Helper::ViewHelper
|
5
|
+
include Qrda::Export::Helper::Cat1ViewHelper
|
6
|
+
include Qrda::Export::Helper::PatientViewHelper
|
7
|
+
include Qrda::Export::Helper::FrequencyHelper
|
8
|
+
include HQMF::Util::EntityHelper
|
9
|
+
|
10
|
+
self.template_path = __dir__
|
11
|
+
|
12
|
+
def initialize(patient, measures, options = {})
|
13
|
+
@patient = patient
|
14
|
+
@qdmPatient = patient.qdmPatient
|
15
|
+
@measures = measures
|
16
|
+
@provider = options[:provider]
|
17
|
+
@patient_address_option = options[:patient_addresses]
|
18
|
+
@patient_telecom_option = options[:patient_telecoms]
|
19
|
+
@patient_email_option = options[:patient_email]
|
20
|
+
@performance_period_start = options[:start_time]
|
21
|
+
@performance_period_end = options[:end_time]
|
22
|
+
@submission_program = options[:submission_program]
|
23
|
+
@medicare_beneficiary_identifier = options[:medicare_beneficiary_identifier]
|
24
|
+
end
|
25
|
+
|
26
|
+
def patient_addresses
|
27
|
+
@patient_address_option ||= [CQM::Address.new(
|
28
|
+
use: 'HP',
|
29
|
+
street: ['202 Burlington Rd.'],
|
30
|
+
city: 'Bedford',
|
31
|
+
state: 'MA',
|
32
|
+
zip: '01730',
|
33
|
+
country: 'US'
|
34
|
+
)]
|
35
|
+
JSON.parse(@patient_address_option.to_json)
|
36
|
+
end
|
37
|
+
|
38
|
+
def patient_telecoms
|
39
|
+
@patient_telecom_option ||= [CQM::Telecom.new(
|
40
|
+
use: 'HP',
|
41
|
+
value: '555-555-2003'
|
42
|
+
)]
|
43
|
+
JSON.parse(@patient_telecom_option.to_json)
|
44
|
+
end
|
45
|
+
|
46
|
+
def patient_email
|
47
|
+
return unless @patient_email_option
|
48
|
+
telecom_email = [CQM::Telecom.new(
|
49
|
+
use: 'HP',
|
50
|
+
value: @patient_email_option
|
51
|
+
)]
|
52
|
+
JSON.parse(telecom_email.to_json)
|
53
|
+
end
|
54
|
+
|
55
|
+
def patient_characteristic_payer
|
56
|
+
JSON.parse(@qdmPatient.get_data_elements('patient_characteristic', 'payer').to_json)
|
57
|
+
end
|
58
|
+
|
59
|
+
def patient_characteristic_birthdate
|
60
|
+
JSON.parse(@qdmPatient.get_data_elements('patient_characteristic', 'birthdate').to_json)
|
61
|
+
end
|
62
|
+
|
63
|
+
def patient_characteristic_sex
|
64
|
+
JSON.parse(@qdmPatient.get_data_elements('patient_characteristic', 'gender').to_json)
|
65
|
+
end
|
66
|
+
|
67
|
+
def patient_characteristic_race
|
68
|
+
JSON.parse(@qdmPatient.get_data_elements('patient_characteristic', 'race').to_json)
|
69
|
+
end
|
70
|
+
|
71
|
+
def patient_characteristic_ethnicity
|
72
|
+
JSON.parse(@qdmPatient.get_data_elements('patient_characteristic', 'ethnicity').to_json)
|
73
|
+
end
|
74
|
+
|
75
|
+
def adverse_event
|
76
|
+
JSON.parse(@qdmPatient.get_data_elements('adverse_event', nil).to_json)
|
77
|
+
end
|
78
|
+
|
79
|
+
def allergy_intolerance
|
80
|
+
JSON.parse(@qdmPatient.get_data_elements('allergy', 'intolerance').to_json)
|
81
|
+
end
|
82
|
+
|
83
|
+
def assessment_order
|
84
|
+
JSON.parse(@qdmPatient.get_data_elements('assessment', 'order').to_json)
|
85
|
+
end
|
86
|
+
|
87
|
+
def assessment_performed
|
88
|
+
JSON.parse(@qdmPatient.get_data_elements('assessment', 'performed').to_json)
|
89
|
+
end
|
90
|
+
|
91
|
+
def assessment_recommended
|
92
|
+
JSON.parse(@qdmPatient.get_data_elements('assessment', 'recommended').to_json)
|
93
|
+
end
|
94
|
+
|
95
|
+
def communication_performed
|
96
|
+
JSON.parse(@qdmPatient.get_data_elements('communication', 'performed').to_json)
|
97
|
+
end
|
98
|
+
|
99
|
+
def diagnosis
|
100
|
+
JSON.parse(@qdmPatient.get_data_elements('condition', nil).to_json)
|
101
|
+
end
|
102
|
+
|
103
|
+
def device_applied
|
104
|
+
JSON.parse(@qdmPatient.get_data_elements('device', 'applied').to_json)
|
105
|
+
end
|
106
|
+
|
107
|
+
def device_order
|
108
|
+
JSON.parse(@qdmPatient.get_data_elements('device', 'order').to_json)
|
109
|
+
end
|
110
|
+
|
111
|
+
def device_recommended
|
112
|
+
JSON.parse(@qdmPatient.get_data_elements('device', 'recommended').to_json)
|
113
|
+
end
|
114
|
+
|
115
|
+
def diagnostic_study_order
|
116
|
+
JSON.parse(@qdmPatient.get_data_elements('diagnostic_study', 'order').to_json)
|
117
|
+
end
|
118
|
+
|
119
|
+
def diagnostic_study_performed
|
120
|
+
JSON.parse(@qdmPatient.get_data_elements('diagnostic_study', 'performed').to_json)
|
121
|
+
end
|
122
|
+
|
123
|
+
def diagnostic_study_recommended
|
124
|
+
JSON.parse(@qdmPatient.get_data_elements('diagnostic_study', 'recommended').to_json)
|
125
|
+
end
|
126
|
+
|
127
|
+
def encounter_order
|
128
|
+
JSON.parse(@qdmPatient.get_data_elements('encounter', 'order').to_json)
|
129
|
+
end
|
130
|
+
|
131
|
+
def encounter_performed
|
132
|
+
JSON.parse(@qdmPatient.get_data_elements('encounter', 'performed').to_json)
|
133
|
+
end
|
134
|
+
|
135
|
+
def encounter_recommended
|
136
|
+
JSON.parse(@qdmPatient.get_data_elements('encounter', 'recommended').to_json)
|
137
|
+
end
|
138
|
+
|
139
|
+
def family_history
|
140
|
+
JSON.parse(@qdmPatient.get_data_elements('family_history', nil).to_json)
|
141
|
+
end
|
142
|
+
|
143
|
+
def immunization_administered
|
144
|
+
JSON.parse(@qdmPatient.get_data_elements('immunization', 'administered').to_json)
|
145
|
+
end
|
146
|
+
|
147
|
+
def immunization_order
|
148
|
+
JSON.parse(@qdmPatient.get_data_elements('immunization', 'order').to_json)
|
149
|
+
end
|
150
|
+
|
151
|
+
def intervention_order
|
152
|
+
JSON.parse(@qdmPatient.get_data_elements('intervention', 'order').to_json)
|
153
|
+
end
|
154
|
+
|
155
|
+
def intervention_performed
|
156
|
+
JSON.parse(@qdmPatient.get_data_elements('intervention', 'performed').to_json)
|
157
|
+
end
|
158
|
+
|
159
|
+
def intervention_recommended
|
160
|
+
JSON.parse(@qdmPatient.get_data_elements('intervention', 'recommended').to_json)
|
161
|
+
end
|
162
|
+
|
163
|
+
def laboratory_test_order
|
164
|
+
JSON.parse(@qdmPatient.get_data_elements('laboratory_test', 'order').to_json)
|
165
|
+
end
|
166
|
+
|
167
|
+
def laboratory_test_performed
|
168
|
+
JSON.parse(@qdmPatient.get_data_elements('laboratory_test', 'performed').to_json)
|
169
|
+
end
|
170
|
+
|
171
|
+
def laboratory_test_recommended
|
172
|
+
JSON.parse(@qdmPatient.get_data_elements('laboratory_test', 'recommended').to_json)
|
173
|
+
end
|
174
|
+
|
175
|
+
def medication_active
|
176
|
+
JSON.parse(@qdmPatient.get_data_elements('medication', 'active').to_json)
|
177
|
+
end
|
178
|
+
|
179
|
+
def medication_administered
|
180
|
+
JSON.parse(@qdmPatient.get_data_elements('medication', 'administered').to_json) + JSON.parse(@qdmPatient.get_data_elements('substance', 'administered').to_json)
|
181
|
+
end
|
182
|
+
|
183
|
+
def medication_discharge
|
184
|
+
JSON.parse(@qdmPatient.get_data_elements('medication', 'discharge').to_json)
|
185
|
+
end
|
186
|
+
|
187
|
+
def medication_dispensed
|
188
|
+
JSON.parse(@qdmPatient.get_data_elements('medication', 'dispensed').to_json)
|
189
|
+
end
|
190
|
+
|
191
|
+
def medication_order
|
192
|
+
JSON.parse(@qdmPatient.get_data_elements('medication', 'order').to_json)
|
193
|
+
end
|
194
|
+
|
195
|
+
def patient_care_experience
|
196
|
+
JSON.parse(@qdmPatient.dataElements.where(hqmfOid: { '$in' => HQMF::Util::HQMFTemplateHelper.get_all_hqmf_oids('patient_care_experience', '') }).to_json)
|
197
|
+
end
|
198
|
+
|
199
|
+
def patient_characteristic_clinical_trial_participant
|
200
|
+
JSON.parse(@qdmPatient.get_data_elements('patient_characteristic', 'clinical_trial_participant').to_json)
|
201
|
+
end
|
202
|
+
|
203
|
+
def patient_characteristic_expired
|
204
|
+
JSON.parse(@qdmPatient.get_data_elements('patient_characteristic', 'expired').to_json)
|
205
|
+
end
|
206
|
+
|
207
|
+
def physical_exam_order
|
208
|
+
JSON.parse(@qdmPatient.get_data_elements('physical_exam', 'order').to_json)
|
209
|
+
end
|
210
|
+
|
211
|
+
def physical_exam_performed
|
212
|
+
JSON.parse(@qdmPatient.get_data_elements('physical_exam', 'performed').to_json)
|
213
|
+
end
|
214
|
+
|
215
|
+
def physical_exam_recommended
|
216
|
+
JSON.parse(@qdmPatient.get_data_elements('physical_exam', 'recommended').to_json)
|
217
|
+
end
|
218
|
+
|
219
|
+
def procedure_order
|
220
|
+
JSON.parse(@qdmPatient.get_data_elements('procedure', 'order').to_json)
|
221
|
+
end
|
222
|
+
|
223
|
+
def procedure_performed
|
224
|
+
JSON.parse(@qdmPatient.get_data_elements('procedure', 'performed').to_json)
|
225
|
+
end
|
226
|
+
|
227
|
+
def procedure_recommended
|
228
|
+
JSON.parse(@qdmPatient.get_data_elements('procedure', 'recommended').to_json)
|
229
|
+
end
|
230
|
+
|
231
|
+
def program_participation
|
232
|
+
JSON.parse(@qdmPatient.get_data_elements('participation', nil).to_json)
|
233
|
+
end
|
234
|
+
|
235
|
+
def provider_care_experience
|
236
|
+
JSON.parse(@qdmPatient.dataElements.where(hqmfOid: { '$in' => HQMF::Util::HQMFTemplateHelper.get_all_hqmf_oids('provider_care_experience', '') }).to_json)
|
237
|
+
end
|
238
|
+
|
239
|
+
def related_person
|
240
|
+
JSON.parse(@qdmPatient.get_data_elements('related_person', nil).to_json)
|
241
|
+
end
|
242
|
+
|
243
|
+
def substance_administered
|
244
|
+
JSON.parse(@qdmPatient.get_data_elements('substance', 'administered').to_json)
|
245
|
+
end
|
246
|
+
|
247
|
+
def substance_order
|
248
|
+
JSON.parse(@qdmPatient.get_data_elements('substance', 'order').to_json)
|
249
|
+
end
|
250
|
+
|
251
|
+
def substance_recommended
|
252
|
+
JSON.parse(@qdmPatient.get_data_elements('substance', 'recommended').to_json)
|
253
|
+
end
|
254
|
+
|
255
|
+
def symptom
|
256
|
+
JSON.parse(@qdmPatient.get_data_elements('symptom', nil).to_json)
|
257
|
+
end
|
258
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<participant typeCode="DEV">
|
2
|
+
<associatedEntity classCode="RGPR">
|
3
|
+
<!-- CMS EHR Certification Number (formerly known as Office of the
|
4
|
+
National Coordinator Certification Number). Note, this is a test
|
5
|
+
file, and the provided ID is not for a certified product set. -->
|
6
|
+
<id extension="0015CPV4ZTB4WBU" root="2.16.840.1.113883.3.2074.1"/>
|
7
|
+
</associatedEntity>
|
8
|
+
</participant>
|
@@ -0,0 +1,65 @@
|
|
1
|
+
<recordTarget>
|
2
|
+
<patientRole>
|
3
|
+
<id extension="{{mrn}}" root="1.3.6.1.4.1.115" />
|
4
|
+
{{#medicare_beneficiary_identifier}}
|
5
|
+
<id extension="{{medicare_beneficiary_identifier}}" root="2.16.840.1.113883.4.927" />
|
6
|
+
{{/medicare_beneficiary_identifier}}
|
7
|
+
{{#patient_addresses}}
|
8
|
+
<addr use="{{use}}">
|
9
|
+
{{#street}}
|
10
|
+
<streetAddressLine>{{.}}</streetAddressLine>
|
11
|
+
{{/street}}
|
12
|
+
<city>{{city}}</city>
|
13
|
+
<state>{{state}}</state>
|
14
|
+
<postalCode>{{zip}}</postalCode>
|
15
|
+
<country>{{country}}</country>
|
16
|
+
</addr>
|
17
|
+
{{/patient_addresses}}
|
18
|
+
{{#patient_telecoms}}
|
19
|
+
<telecom use="{{use}}" value="tel:{{value}}"/>
|
20
|
+
{{/patient_telecoms}}
|
21
|
+
{{#patient_email}}
|
22
|
+
<telecom use="{{use}}" value="mailto:{{value}}"/>
|
23
|
+
{{/patient_email}}
|
24
|
+
<patient>
|
25
|
+
{{#patient}}
|
26
|
+
<name>
|
27
|
+
<given>{{given_name}}</given>
|
28
|
+
<family>{{familyName}}</family>
|
29
|
+
</name>
|
30
|
+
{{/patient}}
|
31
|
+
{{#patient_characteristic_sex}}
|
32
|
+
{{#dataElementCodes}}
|
33
|
+
<administrativeGenderCode {{> _code}}/>
|
34
|
+
{{/dataElementCodes}}
|
35
|
+
{{/patient_characteristic_sex}}
|
36
|
+
{{^patient_characteristic_sex}}
|
37
|
+
<administrativeGenderCode nullFlavor="UNK"/>
|
38
|
+
{{/patient_characteristic_sex}}
|
39
|
+
{{#patient_characteristic_birthdate}}
|
40
|
+
{{{birth_date_time}}}
|
41
|
+
{{/patient_characteristic_birthdate}}
|
42
|
+
{{#patient_characteristic_race}}
|
43
|
+
{{#dataElementCodes}}
|
44
|
+
<raceCode {{> _code}}/>
|
45
|
+
{{/dataElementCodes}}
|
46
|
+
{{/patient_characteristic_race}}
|
47
|
+
{{^patient_characteristic_race}}
|
48
|
+
<raceCode nullFlavor="UNK"/>
|
49
|
+
{{/patient_characteristic_race}}
|
50
|
+
{{#patient_characteristic_ethnicity}}
|
51
|
+
{{#dataElementCodes}}
|
52
|
+
<ethnicGroupCode {{> _code}}/>
|
53
|
+
{{/dataElementCodes}}
|
54
|
+
{{/patient_characteristic_ethnicity}}
|
55
|
+
{{^patient_characteristic_ethnicity}}
|
56
|
+
<ethnicGroupCode nullFlavor="UNK"/>
|
57
|
+
{{/patient_characteristic_ethnicity}}
|
58
|
+
<languageCommunication>
|
59
|
+
<templateId root="2.16.840.1.113883.3.88.11.83.2" assigningAuthorityName="HITSP/C83"/>
|
60
|
+
<templateId root="1.3.6.1.4.1.19376.1.5.3.1.2.1" assigningAuthorityName="IHE/PCC"/>
|
61
|
+
<languageCode code="eng"/>
|
62
|
+
</languageCommunication>
|
63
|
+
</patient>
|
64
|
+
</patientRole>
|
65
|
+
</recordTarget>
|
@@ -0,0 +1,70 @@
|
|
1
|
+
<entry>
|
2
|
+
<!--Medication Order -->
|
3
|
+
<substanceAdministration classCode="SBADM" moodCode="RQO" {{{negation_ind}}}>
|
4
|
+
<templateId root="2.16.840.1.113883.10.20.22.4.42" extension="2014-06-09"/>
|
5
|
+
<!-- Medication, Order template -->
|
6
|
+
<templateId root="2.16.840.1.113883.10.20.24.3.47" extension="2019-12-01"/>
|
7
|
+
<id root="1.3.6.1.4.1.115" extension="{{object_id}}"/>
|
8
|
+
<text>{{description}}</text>
|
9
|
+
<statusCode code="active"/>
|
10
|
+
{{#relevantPeriod}}
|
11
|
+
<!-- QDM Attribute: Relevant Period -->
|
12
|
+
{{{medication_duration_effective_time}}}
|
13
|
+
{{/relevantPeriod}}
|
14
|
+
{{^relevantPeriod}}
|
15
|
+
{{#authorDatetime}}
|
16
|
+
<!-- QDM Attribute: Relevant Period -->
|
17
|
+
{{{medication_duration_author_effective_time}}}
|
18
|
+
{{/authorDatetime}}
|
19
|
+
{{/relevantPeriod}}
|
20
|
+
{{> qrda_templates/template_partials/_medication_details}}
|
21
|
+
<consumable>
|
22
|
+
<manufacturedProduct classCode="MANU">
|
23
|
+
<!-- Medication Information (consolidation) template -->
|
24
|
+
<templateId root="2.16.840.1.113883.10.20.22.4.23" extension="2014-06-09"/>
|
25
|
+
<id root="{{random_id}}"/>
|
26
|
+
<manufacturedMaterial>
|
27
|
+
<!-- QDM Attribute: Code -->
|
28
|
+
{{> _codes}}
|
29
|
+
</manufacturedMaterial>
|
30
|
+
</manufacturedProduct>
|
31
|
+
</consumable>
|
32
|
+
{{#authorDatetime}}
|
33
|
+
<!-- QDM Attribute: Author dateTime -->
|
34
|
+
{{> qrda_templates/template_partials/_author}}
|
35
|
+
{{/authorDatetime}}
|
36
|
+
{{#setting}}
|
37
|
+
<participant typeCode="LOC">
|
38
|
+
<participantRole>
|
39
|
+
<!-- QDM Attribute: Setting -->
|
40
|
+
<code {{> _code}}/>
|
41
|
+
</participantRole>
|
42
|
+
</participant>
|
43
|
+
{{/setting}}
|
44
|
+
{{#prescriber}}
|
45
|
+
<!-- QDM Attribute: Prescriber -->
|
46
|
+
<participant typeCode="PRF">
|
47
|
+
{{> qrda_templates/template_partials/_entity}}
|
48
|
+
</participant>
|
49
|
+
{{/prescriber}}
|
50
|
+
{{#reason}}
|
51
|
+
<!-- QDM Attribute: Reason -->
|
52
|
+
{{> qrda_templates/template_partials/_reason}}
|
53
|
+
{{/reason}}
|
54
|
+
{{#negationRationale}}
|
55
|
+
<!-- QDM Attribute: Negation Rationale -->
|
56
|
+
{{> qrda_templates/template_partials/_reason}}
|
57
|
+
{{/negationRationale}}
|
58
|
+
{{#daysSupplied}}
|
59
|
+
<entryRelationship typeCode="REFR">
|
60
|
+
{{> qrda_templates/template_partials/_days_supplied}}
|
61
|
+
</entryRelationship>
|
62
|
+
{{/daysSupplied}}
|
63
|
+
{{#supply}}
|
64
|
+
<!-- QDM Attribute: Supply -->
|
65
|
+
<entryRelationship typeCode="COMP">
|
66
|
+
{{> qrda_templates/template_partials/_medication_supply_request}}
|
67
|
+
</entryRelationship>
|
68
|
+
{{/supply}}
|
69
|
+
</substanceAdministration>
|
70
|
+
</entry>
|
@@ -3,10 +3,8 @@
|
|
3
3
|
<typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/>
|
4
4
|
<!-- US Realm Header Template Id -->
|
5
5
|
<templateId root="2.16.840.1.113883.10.20.27.1.1" extension="2020-12-01"/>
|
6
|
-
|
7
|
-
|
8
|
-
<templateId root="2.16.840.1.113883.10.20.27.1.2" extension="2021-07-01"/>
|
9
|
-
{{/ry2022_submission?}}
|
6
|
+
<!-- QRDA Category III Report - CMS (V7) -->
|
7
|
+
<templateId root="2.16.840.1.113883.10.20.27.1.2" extension="2022-12-01"/>
|
10
8
|
<!-- This is the globally unique identifier for this QRDA document -->
|
11
9
|
<id root="{{random_id}}"/>
|
12
10
|
<!-- QRDA III document type code -->
|
@@ -1,6 +1,9 @@
|
|
1
1
|
<participant typeCode="DEV">
|
2
2
|
<associatedEntity classCode="RGPR">
|
3
|
-
|
3
|
+
<!-- CMS EHR Certification Number (formerly known as Office of the
|
4
|
+
National Coordinator Certification Number). Note, this is a test
|
5
|
+
file, and the provided ID is not for a certified product set. -->
|
6
|
+
<id root="2.16.840.1.113883.3.2074.1" extension="0015CPV4ZTB4WBU"/>
|
4
7
|
<code code="129465004" displayName="medical record, device" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED-CT"/>
|
5
8
|
</associatedEntity>
|
6
9
|
</participant>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<participant typeCode="DEV">
|
2
|
+
<associatedEntity classCode="RGPR">
|
3
|
+
<!-- CMS EHR Certification Number (formerly known as Office of the
|
4
|
+
National Coordinator Certification Number). Note, this is a test
|
5
|
+
file, and the provided ID is not for a certified product set. -->
|
6
|
+
<id root="2.16.840.1.113883.3.2074.1" extension="0015CPV4ZTB4WBU"/>
|
7
|
+
<code code="129465004" displayName="medical record, device" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED-CT"/>
|
8
|
+
</associatedEntity>
|
9
|
+
</participant>
|
@@ -55,22 +55,30 @@ module Qrda
|
|
55
55
|
self['value'].to_f
|
56
56
|
end
|
57
57
|
|
58
|
+
def refills_as_repeat_number
|
59
|
+
self['refills'] + 1
|
60
|
+
end
|
61
|
+
|
58
62
|
def dose_quantity_value
|
59
|
-
return "<doseQuantity value=\"#{value_as_float}\" unit=\"#{self['unit']}\"/>" if self['unit']
|
63
|
+
return "<doseQuantity value=\"#{value_as_float}\" unit=\"#{self['unit']}\"/>" if self['unit'] && self['unit'] != ''
|
60
64
|
"<doseQuantity value=\"#{value_as_float}\" />"
|
61
65
|
end
|
62
66
|
|
63
67
|
def result_value
|
64
68
|
return "<value xsi:type=\"CD\" nullFlavor=\"UNK\"/>" unless self['result']
|
65
|
-
|
66
69
|
result_string = if self['result'].is_a? Array
|
67
70
|
result_value_as_string(self['result'][0])
|
68
71
|
elsif self['result'].is_a? Hash
|
69
72
|
result_value_as_string(self['result'])
|
70
73
|
elsif self['result'].is_a? String
|
71
|
-
|
74
|
+
begin
|
75
|
+
DateTime.parse self['result']
|
76
|
+
"<value xsi:type=\"TS\" #{value_or_null_flavor(self['result'])}/>"
|
77
|
+
rescue StandardError
|
78
|
+
"<value xsi:type=\"ST\">#{self['result']}</value>"
|
79
|
+
end
|
72
80
|
elsif !self['result'].nil?
|
73
|
-
|
81
|
+
integer_or_pq(self['result'])
|
74
82
|
end
|
75
83
|
result_string
|
76
84
|
end
|
@@ -79,7 +87,17 @@ module Qrda
|
|
79
87
|
return "<value xsi:type=\"CD\" nullFlavor=\"UNK\"/>" unless result
|
80
88
|
oid = result['system'] || result['codeSystem']
|
81
89
|
return "<value xsi:type=\"CD\" code=\"#{result['code']}\" codeSystem=\"#{oid}\" codeSystemName=\"#{HQMF::Util::CodeSystemHelper.code_system_for(oid)}\"/>" if result['code']
|
82
|
-
return
|
90
|
+
return integer_or_pq(result['value'], result['unit']) if result['unit'] && result['unit'] != ''
|
91
|
+
end
|
92
|
+
|
93
|
+
def integer_or_pq(number, unit = nil)
|
94
|
+
i = number.to_i
|
95
|
+
f = number.to_f
|
96
|
+
if i == f
|
97
|
+
unit ? "<value xsi:type=\"PQ\" value=\"#{i}\" unit=\"#{unit}\"/>" : "<value xsi:type=\"INT\" value=\"#{i}\"/>"
|
98
|
+
else
|
99
|
+
unit ? "<value xsi:type=\"PQ\" value=\"#{f}\" unit=\"#{unit}\"/>" : "<value xsi:type=\"REAL\" value=\"#{f}\"/>"
|
100
|
+
end
|
83
101
|
end
|
84
102
|
|
85
103
|
def authordatetime_or_dispenserid?
|
@@ -4,7 +4,7 @@ module Qrda
|
|
4
4
|
module Helper
|
5
5
|
module ViewHelper
|
6
6
|
def measures
|
7
|
-
@measures.
|
7
|
+
@measures.as_json
|
8
8
|
end
|
9
9
|
|
10
10
|
def random_id
|
@@ -22,6 +22,14 @@ module Qrda
|
|
22
22
|
def submission_program
|
23
23
|
@submission_program
|
24
24
|
end
|
25
|
+
|
26
|
+
def medicare_beneficiary_identifier
|
27
|
+
@medicare_beneficiary_identifier
|
28
|
+
end
|
29
|
+
|
30
|
+
def hicn
|
31
|
+
@hicn
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
27
35
|
end
|
@@ -47,8 +47,8 @@ module QRDA
|
|
47
47
|
entry_qrda_id = extract_id(entry_element, @id_xpath)
|
48
48
|
# Create a hash to map all of entry.ids to the same QRDA ids. This will be used to merge QRDA entries
|
49
49
|
# that represent the same event.
|
50
|
-
@entry_id_map["#{entry_qrda_id.value}
|
51
|
-
@entry_id_map["#{entry_qrda_id.value}
|
50
|
+
@entry_id_map["#{entry_qrda_id.value}***#{entry_qrda_id.namingSystem}"] ||= []
|
51
|
+
@entry_id_map["#{entry_qrda_id.value}***#{entry_qrda_id.namingSystem}"] << entry.id
|
52
52
|
entry.dataElementCodes = extract_codes(entry_element, @code_xpath)
|
53
53
|
extract_dates(entry_element, entry)
|
54
54
|
if @result_xpath
|
@@ -77,7 +77,12 @@ module QRDA
|
|
77
77
|
code_list << code_if_present(code_element)
|
78
78
|
translations = code_element.xpath('cda:translation')
|
79
79
|
translations.each do |translation|
|
80
|
-
|
80
|
+
translation_code = code_if_present(translation)
|
81
|
+
next unless translation_code
|
82
|
+
|
83
|
+
code_list << translation_code
|
84
|
+
@warnings << ValidationError.new(message: "Translation code #{translation_code.system}:#{translation_code.code} may not be used for eCQM calculation by a receiving system. Ensure that the root code includes a code from the eCQM valueset.",
|
85
|
+
location: coded_element.path)
|
81
86
|
end
|
82
87
|
end
|
83
88
|
code_list.compact
|
@@ -193,7 +198,14 @@ module QRDA
|
|
193
198
|
return unless value_element && !value_element['nullFlavor']
|
194
199
|
value = value_element['value']
|
195
200
|
if value.present?
|
196
|
-
|
201
|
+
if ['TS'].include? value_element.at_xpath("@xsi:type")&.value
|
202
|
+
begin
|
203
|
+
return DateTime.parse(value_element['value'])
|
204
|
+
rescue StandardError
|
205
|
+
return nil
|
206
|
+
end
|
207
|
+
end
|
208
|
+
return value.strip.to_f if unitless?(value_element)
|
197
209
|
|
198
210
|
return QDM::Quantity.new(value.strip.to_f, value_element['unit'])
|
199
211
|
elsif value_element['code'].present?
|
@@ -208,6 +220,12 @@ module QRDA
|
|
208
220
|
end
|
209
221
|
end
|
210
222
|
|
223
|
+
def unitless?(value_element)
|
224
|
+
return true if value_element['unit'].nil?
|
225
|
+
return true if value_element['unit'] == '1'
|
226
|
+
return true if value_element['unit'][0] == '{' && value_element['unit'][-1] == '}'
|
227
|
+
end
|
228
|
+
|
211
229
|
def extract_reason(parent_element)
|
212
230
|
return unless @reason_xpath
|
213
231
|
reason_element = parent_element.xpath(@reason_xpath)
|
@@ -254,6 +272,15 @@ module QRDA
|
|
254
272
|
QDM::Quantity.new(scalar_element['value'].to_f, scalar_element['unit'])
|
255
273
|
end
|
256
274
|
|
275
|
+
def extract_refills(parent_element, repeat_number_xpath)
|
276
|
+
repeat_number_element = parent_element.at_xpath(repeat_number_xpath)
|
277
|
+
return unless repeat_number_element && repeat_number_element['value'].present?
|
278
|
+
|
279
|
+
# Refills is the Repeat Number - 1
|
280
|
+
repeat_number = repeat_number_element['value'].to_i
|
281
|
+
repeat_number.positive? ? repeat_number - 1 : 0
|
282
|
+
end
|
283
|
+
|
257
284
|
def extract_components(parent_element)
|
258
285
|
component_elements = parent_element.xpath(@components_xpath)
|
259
286
|
components = []
|
@@ -1,18 +1,18 @@
|
|
1
1
|
module QRDA
|
2
2
|
module Cat1
|
3
3
|
class EncounterPerformedImporter < SectionImporter
|
4
|
-
def initialize(entry_finder = QRDA::Cat1::EntryFinder.new("./cda:entry/cda:
|
4
|
+
def initialize(entry_finder = QRDA::Cat1::EntryFinder.new("./cda:entry/cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.23']"))
|
5
5
|
super(entry_finder)
|
6
|
-
@id_xpath = './cda:
|
7
|
-
@code_xpath = "./cda:
|
8
|
-
@relevant_period_xpath = "./cda:
|
9
|
-
@author_datetime_xpath = "./cda:
|
10
|
-
@admission_source_xpath = "./cda:
|
11
|
-
@discharge_disposition_xpath = "./
|
12
|
-
@facility_locations_xpath = "./cda:
|
13
|
-
@clazz_xpath = "./cda:entryRelationship/cda:
|
14
|
-
@diagnosis_xpath = "./cda:entryRelationship/cda:
|
15
|
-
@related_to_xpath = "./
|
6
|
+
@id_xpath = './cda:id'
|
7
|
+
@code_xpath = "./cda:code"
|
8
|
+
@relevant_period_xpath = "./cda:effectiveTime"
|
9
|
+
@author_datetime_xpath = "./cda:author[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.155']/cda:time"
|
10
|
+
@admission_source_xpath = "./cda:participant/cda:participantRole[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.151']/cda:code"
|
11
|
+
@discharge_disposition_xpath = "./sdtc:dischargeDispositionCode"
|
12
|
+
@facility_locations_xpath = "./cda:participant[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.100']"
|
13
|
+
@clazz_xpath = "./cda:entryRelationship/cda:act[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.171']/cda:code"
|
14
|
+
@diagnosis_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.168']"
|
15
|
+
@related_to_xpath = "./sdtc:inFulfillmentOf1/sdtc:actReference"
|
16
16
|
@entry_class = QDM::EncounterPerformed
|
17
17
|
end
|
18
18
|
|
@@ -27,7 +27,7 @@ module QRDA
|
|
27
27
|
los = encounter_performed.relevantPeriod.high.to_date - encounter_performed.relevantPeriod.low.to_date
|
28
28
|
encounter_performed.lengthOfStay = QDM::Quantity.new(los.to_i, 'd')
|
29
29
|
end
|
30
|
-
entity = extract_entity(entry_element, "./cda:
|
30
|
+
entity = extract_entity(entry_element, "./cda:participant[@typeCode='PRF']")
|
31
31
|
encounter_performed.participant.concat(entity) if entity
|
32
32
|
extract_modifier_code(encounter_performed, entry_element)
|
33
33
|
encounter_performed.relatedTo = extract_related_to(entry_element)
|
@@ -18,7 +18,7 @@ module QRDA
|
|
18
18
|
|
19
19
|
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
20
20
|
medication_discharge = super
|
21
|
-
medication_discharge.refills =
|
21
|
+
medication_discharge.refills = extract_refills(entry_element, @refills_xpath)
|
22
22
|
medication_discharge.dosage = extract_scalar(entry_element, @dosage_xpath)
|
23
23
|
medication_discharge.supply = extract_scalar(entry_element, @supply_xpath)
|
24
24
|
medication_discharge.frequency = frequency_as_coded_value(entry_element, @frequency_xpath)
|
@@ -19,7 +19,7 @@ module QRDA
|
|
19
19
|
|
20
20
|
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
21
21
|
medication_dispensed = super
|
22
|
-
medication_dispensed.refills =
|
22
|
+
medication_dispensed.refills = extract_refills(entry_element, @refills_xpath)
|
23
23
|
medication_dispensed.dosage = extract_scalar(entry_element, @dosage_xpath)
|
24
24
|
medication_dispensed.supply = extract_scalar(entry_element, @supply_xpath)
|
25
25
|
medication_dispensed.frequency = frequency_as_coded_value(entry_element, @frequency_xpath)
|
@@ -25,7 +25,7 @@ module QRDA
|
|
25
25
|
medication_order.dosage = extract_scalar(entry_element, @dosage_xpath)
|
26
26
|
medication_order.supply = extract_scalar(entry_element, @supply_xpath)
|
27
27
|
medication_order.frequency = frequency_as_coded_value(entry_element, @frequency_xpath)
|
28
|
-
medication_order.refills =
|
28
|
+
medication_order.refills = extract_refills(entry_element, @refills_xpath)
|
29
29
|
medication_order.route = code_if_present(entry_element.at_xpath(@route_xpath))
|
30
30
|
medication_order.setting = code_if_present(entry_element.at_xpath(@setting_xpath))
|
31
31
|
medication_order.daysSupplied = extract_scalar(entry_element, @days_supplied_xpath)&.value
|
@@ -21,7 +21,7 @@ module QRDA
|
|
21
21
|
substance_order.dosage = extract_scalar(entry_element, @dosage_xpath)
|
22
22
|
substance_order.supply = extract_scalar(entry_element, @supply_xpath)
|
23
23
|
substance_order.frequency = frequency_as_coded_value(entry_element, @frequency_xpath)
|
24
|
-
substance_order.refills =
|
24
|
+
substance_order.refills = extract_refills(entry_element, @refills_xpath)
|
25
25
|
substance_order.route = code_if_present(entry_element.at_xpath(@route_xpath))
|
26
26
|
substance_order.reason = extract_reason(entry_element)
|
27
27
|
substance_order
|
@@ -18,7 +18,7 @@ module QRDA
|
|
18
18
|
substance_recommended = super
|
19
19
|
substance_recommended.dosage = extract_scalar(entry_element, @dosage_xpath)
|
20
20
|
substance_recommended.frequency = frequency_as_coded_value(entry_element, @frequency_xpath)
|
21
|
-
substance_recommended.refills =
|
21
|
+
substance_recommended.refills = extract_refills(entry_element, @refills_xpath)
|
22
22
|
substance_recommended.route = code_if_present(entry_element.at_xpath(@route_xpath))
|
23
23
|
substance_recommended.reason = extract_reason(entry_element)
|
24
24
|
entity = extract_entity(entry_element, "./cda:participant[@typeCode='PRF']")
|
@@ -67,7 +67,7 @@ module QRDA
|
|
67
67
|
codes_modifiers = {}
|
68
68
|
entry_id_map = {}
|
69
69
|
import_data_elements(patient, doc, entry_id_map, codes, codes_modifiers, warnings)
|
70
|
-
normalize_references(patient, entry_id_map)
|
70
|
+
normalize_references(patient, entry_id_map, warnings)
|
71
71
|
get_demographics(patient, doc, codes)
|
72
72
|
[patient, warnings, codes, codes_modifiers]
|
73
73
|
end
|
@@ -80,9 +80,19 @@ module QRDA
|
|
80
80
|
data_elements, id_map = importer.create_entries(context, nrh)
|
81
81
|
new_data_elements = []
|
82
82
|
|
83
|
-
id_map.
|
84
|
-
|
83
|
+
id_map.each_pair do |key, elem_ids|
|
84
|
+
split_id = key.split('***')
|
85
|
+
id_string = "#{split_id[1]}(root), #{split_id[0]}(extension)"
|
86
|
+
warnings << ValidationError.new(message: "Two or more entries share the Id: #{id_string}.") if elem_ids.length > 1
|
87
|
+
elem_id = elem_ids.last
|
85
88
|
data_element = data_elements.find { |de| de.id == elem_id }
|
89
|
+
|
90
|
+
# If a data_element isn't returned, there was an issue parsing the template, provide a warning
|
91
|
+
if data_element.nil?
|
92
|
+
warnings << ValidationError.new(message: "Error parsing template with Id: #{id_string}.")
|
93
|
+
next
|
94
|
+
end
|
95
|
+
|
86
96
|
# Keep the first element with a shared ID
|
87
97
|
new_data_elements << data_element
|
88
98
|
|
@@ -94,7 +104,7 @@ module QRDA
|
|
94
104
|
unique_element_keys << key_elements_for_determining_encounter_uniqueness(data_element)
|
95
105
|
|
96
106
|
# Loop through all other data elements with the same id
|
97
|
-
elem_ids[
|
107
|
+
elem_ids[0,elem_ids.length - 1].each do |dup_id|
|
98
108
|
dup_element = data_elements.find { |de| de.id == dup_id }
|
99
109
|
dup_element_keys = key_elements_for_determining_encounter_uniqueness(dup_element)
|
100
110
|
# See if a previously selected data element shared all of the keys files
|
@@ -134,13 +144,19 @@ module QRDA
|
|
134
144
|
record.deathdate = DateTime.parse(entry_elements.at_xpath("./cda:effectiveTime/cda:low")['value']).to_i
|
135
145
|
end
|
136
146
|
|
137
|
-
def normalize_references(patient, entry_id_map)
|
147
|
+
def normalize_references(patient, entry_id_map, warnings)
|
138
148
|
patient.qdmPatient.dataElements.each do |data_element|
|
139
149
|
next unless data_element.respond_to?(:relatedTo) && data_element.relatedTo
|
140
150
|
|
141
151
|
relations_to_add = []
|
142
152
|
data_element.relatedTo.each do |related_to|
|
143
|
-
|
153
|
+
relation_to_add = entry_id_map["#{related_to['value']}***#{related_to['namingSystem']}"]
|
154
|
+
# Add the relation if it can be found, otherwise return a warning
|
155
|
+
relations_to_add += relation_to_add unless relation_to_add.nil?
|
156
|
+
if relation_to_add.nil?
|
157
|
+
id_warning_str = "Related To Id: #{related_to['namingSystem']}(root), #{related_to['value']}(extension) cannot be found in QRDA file."
|
158
|
+
warnings << ValidationError.new(message: id_warning_str)
|
159
|
+
end
|
144
160
|
end
|
145
161
|
data_element.relatedTo = relations_to_add.map(&:to_s)
|
146
162
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cqm-reports
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The MITRE Corporation
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cqm-models
|
@@ -89,7 +89,7 @@ dependencies:
|
|
89
89
|
version: 1.8.5
|
90
90
|
- - "<"
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version: 1.
|
92
|
+
version: 1.15.0
|
93
93
|
type: :runtime
|
94
94
|
prerelease: false
|
95
95
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -99,7 +99,7 @@ dependencies:
|
|
99
99
|
version: 1.8.5
|
100
100
|
- - "<"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: 1.
|
102
|
+
version: 1.15.0
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: uuid
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -263,6 +263,11 @@ files:
|
|
263
263
|
- lib/qrda-export/catI-r5/qrda_templates/template_partials/_results.mustache
|
264
264
|
- lib/qrda-export/catI-r5/qrda_templates/template_partials/_severity.mustache
|
265
265
|
- lib/qrda-export/catI-r5/qrda_templates/template_partials/_status.mustache
|
266
|
+
- lib/qrda-export/catI-r52/qrda1_r52.rb
|
267
|
+
- lib/qrda-export/catI-r52/qrda_header/_participant.mustache
|
268
|
+
- lib/qrda-export/catI-r52/qrda_header/_record_target.mustache
|
269
|
+
- lib/qrda-export/catI-r52/qrda_templates/medication_order.mustache
|
270
|
+
- lib/qrda-export/catIII-r2-1/qrda_header/_participant_ehr.mustache
|
266
271
|
- lib/qrda-export/catIII/_continuous_variable_value.mustache
|
267
272
|
- lib/qrda-export/catIII/_header.mustache
|
268
273
|
- lib/qrda-export/catIII/_measure_data.mustache
|
@@ -365,7 +370,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
365
370
|
- !ruby/object:Gem::Version
|
366
371
|
version: '0'
|
367
372
|
requirements: []
|
368
|
-
rubygems_version: 3.1.
|
373
|
+
rubygems_version: 3.1.4
|
369
374
|
signing_key:
|
370
375
|
specification_version: 4
|
371
376
|
summary: A library for import and export of reports for use with electronic Clinical
|