health-data-standards 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec :development_group => :test
4
+
5
+ gem 'rake'
6
+ gem 'pry'
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ This is a project to generate and consume HITSP C32, ASTM CCR and PQRI
2
+
3
+ Environment
4
+ ===========
5
+
6
+ This project currently uses Ruby 1.9.2 and is built using [Bundler](http://gembundler.com/). To get all of the dependencies for the project, first install bundler:
7
+
8
+ gem install bundler
9
+
10
+ Then run bundler to grab all of the necessary gems:
11
+
12
+ bundle install
13
+
14
+ The Quality Measure engine relies on a MongoDB [MongoDB](http://www.mongodb.org/) running a minimum of version 1.8.* or higher. To get and install Mongo refer to:
15
+
16
+ http://www.mongodb.org/display/DOCS/Quickstart
17
+
18
+ Project Practices
19
+ =================
20
+
21
+ Please try to follow our [Coding Style Guides](http://github.com/eedrummer/styleguide). Additionally, we will be using git in a pattern similar to [Vincent Driessen's workflow](http://nvie.com/posts/a-successful-git-branching-model/). While feature branches are encouraged, they are not required to work on the project.
22
+
23
+ License
24
+ =======
25
+
26
+ Copyright 2011 The MITRE Corporation
27
+
28
+ Licensed under the Apache License, Version 2.0 (the "License");
29
+ you may not use this file except in compliance with the License.
30
+ You may obtain a copy of the License at
31
+
32
+ http://www.apache.org/licenses/LICENSE-2.0
33
+
34
+ Unless required by applicable law or agreed to in writing, software
35
+ distributed under the License is distributed on an "AS IS" BASIS,
36
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37
+ See the License for the specific language governing permissions and
38
+ limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << "test"
5
+ t.test_files = FileList['test/**/*_test.rb']
6
+ t.verbose = true
7
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,15 @@
1
+ require 'erubis'
2
+ require 'active_support'
3
+ require 'mongoid'
4
+ require 'uuid'
5
+ require 'quality-measure-engine'
6
+ require 'builder'
7
+
8
+ require_relative 'health-data-standards/export/template_helper'
9
+ require_relative 'health-data-standards/export/view_helper'
10
+ require_relative 'health-data-standards/export/rendering_context'
11
+ require_relative 'health-data-standards/export/c32'
12
+ require_relative 'health-data-standards/export/ccr'
13
+
14
+ require_relative 'health-data-standards/models/entry'
15
+ require_relative 'health-data-standards/models/record'
@@ -0,0 +1,14 @@
1
+ module HealthDataStandards
2
+ module Export
3
+ module C32
4
+ include TemplateHelper
5
+
6
+ def export(patient)
7
+ self.template_format = "c32"
8
+ render(:template => 'show', :locals => {:patient => patient})
9
+ end
10
+
11
+ extend self
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,375 @@
1
+ module HealthDataStandards
2
+ module Export
3
+ module CCR
4
+ # Builds a CCR XML document representing the patient.
5
+ #
6
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
7
+ def export(patient)
8
+ xml = Builder::XmlMarkup.new(:indent => 2)
9
+ xml.ContinuityOfCareRecord("xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
10
+ "xsi:schemaLocation" => "urn:astm-org:CCR CCR_20051109.xsd http://www.w3.org/2001/XMLSchema xmldsig-core-schema.xsd",
11
+ "xmlns" => "urn:astm-org:CCR") do
12
+ xml.CCRDocumentObjectID(patient.id)
13
+ xml.Language do
14
+ xml.Text("English")
15
+ end
16
+ xml.Version("V1.0")
17
+ xml.DateTime do
18
+ #TODO: Need to fix this and not be a hard-coded value
19
+ xml.ExactDateTime(Time.now.xmlschema)
20
+ end
21
+ xml.Patient do
22
+ xml.ActorID(patient.id)
23
+ end
24
+ xml.From do
25
+ xml.ActorLink do
26
+ xml.ActorID("AA0002")
27
+ end
28
+ end
29
+ to_ccr_purpose(xml)
30
+ xml.body do
31
+ to_ccr_problems(xml, patient)
32
+ to_ccr_vitals(xml, patient)
33
+ to_ccr_results(xml, patient)
34
+ to_ccr_encounters(xml, patient)
35
+ to_ccr_medications(xml, patient)
36
+ to_ccr_immunizations(xml, patient)
37
+ to_ccr_procedures(xml, patient)
38
+ to_ccr_allergies(xml, patient)
39
+ end
40
+ to_ccr_actors(xml, patient)
41
+ end
42
+ end
43
+
44
+ extend self
45
+
46
+ private
47
+
48
+ def code_section(xml, codes)
49
+ xml.Code do
50
+ if codes.present?
51
+ codes.each_pair do |code_set, coded_values|
52
+ coded_values.each do |coded_value|
53
+ xml.Value(coded_value)
54
+ xml.CodingSystem(code_set)
55
+ #TODO: Need to fix this and not be a hard-coded value
56
+ xml.Version("2005")
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def active_status_and_source(xml, patient)
64
+ xml.Status do
65
+ xml.Text("Active")
66
+ end
67
+ xml.Source do
68
+ xml.Actor do
69
+ xml.ActorID(patient.id)
70
+ end
71
+ end
72
+ end
73
+
74
+ # Builds the XML snippet for the problems section inside the CCR standard
75
+ #
76
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
77
+ def to_ccr_problems(xml, patient)
78
+ if patient.conditions.present?
79
+ xml.Problems do
80
+ patient.conditions.each_with_index do |condition, index|
81
+ xml.Problem do
82
+ xml.CCRDataObjectID("PR000#{index + 1}")
83
+ xml.DateTime do
84
+ xml.Type do
85
+ xml.Text("Start date")
86
+ end
87
+ #time
88
+ xml.ExactDateTime(convert_to_ccr_time_string(condition.time))
89
+ end
90
+ xml.Type do
91
+ #TODO: Need to fix this and not be a hard-coded value
92
+ xml.Text("Diagnosis")
93
+ end
94
+ xml.Description do
95
+ xml.Text(condition.description)
96
+ code_section(xml, condition.codes)
97
+ end
98
+ active_status_and_source(xml, patient)
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ # Builds the XML snippet for the encounters section inside the CCR standard
106
+ #
107
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
108
+ def to_ccr_encounters(xml, patient)
109
+ if patient.encounters.present?
110
+ xml.Encounters do
111
+ patient.encounters.each_with_index do |encounter, index|
112
+ xml.Encounter do
113
+ xml.CCRDataObjectID("EN000#{index + 1}")
114
+ xml.DateTime do
115
+ xml.Type do
116
+ xml.Text("Encounter Date")
117
+ end
118
+ #time
119
+ xml.ExactDateTime(convert_to_ccr_time_string(encounter.time))
120
+ end
121
+ xml.Description do
122
+ xml.Text(encounter.description)
123
+ code_section(xml, encounter.codes)
124
+ end
125
+ active_status_and_source(xml, patient)
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # Builds the XML snippet for the vitals section inside the CCR standard
133
+ #
134
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
135
+ def to_ccr_vitals(xml, patient)
136
+ if patient.vital_signs.present?
137
+ xml.VitalSigns do
138
+ patient.vital_signs.each_with_index do |vital_sign, index|
139
+ xml.Result do
140
+ xml.CCRDataObjectID("VT000#{index + 1}")
141
+ xml.DateTime do
142
+ xml.Type do
143
+ xml.Text("Start date")
144
+ end
145
+ #time
146
+ xml.ExactDateTime(convert_to_ccr_time_string(vital_sign.time))
147
+ end
148
+ xml.Description do
149
+ xml.Text(vital_sign.description)
150
+ code_section(xml, vital_sign.codes)
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ # Builds the XML snippet for the medications section inside the CCR standard
159
+ #
160
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
161
+ def to_ccr_medications(xml, patient)
162
+ if patient.medications.present?
163
+ xml.Medications do
164
+ patient.medications.each_with_index do |medication, index|
165
+ xml.Medication do
166
+ xml.CCRDataObjectID("MD000#{index + 1}")
167
+ xml.DateTime do
168
+ xml.Type do
169
+ xml.Text("Prescription Date")
170
+ end
171
+ #time
172
+ xml.ExactDateTime(convert_to_ccr_time_string(medication.time))
173
+ end
174
+ xml.Type do
175
+ xml.Text("Medication")
176
+ end
177
+ active_status_and_source(xml, patient)
178
+ xml.Product do
179
+ xml.ProductName do
180
+ xml.Text(medication.description)
181
+ end
182
+ xml.BrandName do
183
+ xml.Text(medication.description)
184
+ code_section(xml, medication.codes)
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+
193
+ # Builds the XML snippet for the medications section inside the CCR standard
194
+ #
195
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
196
+ def to_ccr_immunizations(xml, patient)
197
+ if patient.immunizations.present?
198
+ xml.Immunizations do
199
+ patient.immunizations.each_with_index do |immunization, index|
200
+ xml.Immunization do
201
+ xml.CCRDataObjectID("IM000#{index + 1}")
202
+ xml.DateTime do
203
+ xml.Type do
204
+ xml.Text("Prescription Date")
205
+ end
206
+ #time
207
+ xml.ExactDateTime(convert_to_ccr_time_string(immunization.time))
208
+ end
209
+ xml.Type do
210
+ xml.Text("Immunization")
211
+ end
212
+ active_status_and_source(xml, patient)
213
+ xml.Product do
214
+ xml.ProductName do
215
+ xml.Text(immunization.description)
216
+ end
217
+ xml.BrandName do
218
+ xml.Text(immunization.description)
219
+ code_section(xml, immunization.codes)
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ # Builds the XML snippet for the lab section inside the CCR standard
229
+ #
230
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
231
+ def to_ccr_results(xml, patient)
232
+ if patient.results.present?
233
+ xml.Results do
234
+ patient.results.each_with_index do |lab_result, index|
235
+ xml.Result do
236
+ xml.CCRDataObjectID("LB000#{index + 1}")
237
+ xml.DateTime do
238
+ xml.Type do
239
+ xml.Text("Start date")
240
+ end
241
+ #time
242
+ xml.ExactDateTime(convert_to_ccr_time_string(lab_result.time))
243
+ end
244
+ xml.Description do
245
+ xml.Text(lab_result.description)
246
+ code_section(xml, lab_result.codes)
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ # Builds the XML snippet for the procedures section inside the CCR standard
255
+ #
256
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
257
+ def to_ccr_procedures(xml, patient)
258
+ if patient.procedures.present?
259
+ xml.Procedures do
260
+ patient.procedures.each_with_index do |procedure, index|
261
+ xml.Procedure do
262
+ xml.CCRDataObjectID("PR000#{index + 1}")
263
+ xml.DateTime do
264
+ xml.Type do
265
+ xml.Text("Service date")
266
+ end
267
+ #time
268
+ xml.ExactDateTime(convert_to_ccr_time_string(procedure.time))
269
+ end
270
+ xml.Description do
271
+ xml.Text(procedure.description)
272
+ code_section(xml, procedure.codes)
273
+ end
274
+ xml.Status do
275
+ xml.Text("Active")
276
+ end
277
+ end
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ def to_ccr_allergies(xml, patient)
284
+ if patient.allergies.present?
285
+ xml.Alerts do
286
+ patient.allergies.each_with_index do |allergy, index|
287
+ xml.Alert do
288
+ xml.CCRDataObjectID("AL000#{index + 1}")
289
+ xml.DateTime do
290
+ xml.Type do
291
+ xml.Text("Initial Occurrence")
292
+ end
293
+ #time
294
+ xml.ExactDateTime(convert_to_ccr_time_string(allergy.time))
295
+ end
296
+ xml.Type do
297
+ xml.Text("Allergy")
298
+ end
299
+ xml.Description do
300
+ xml.Text(allergy.description)
301
+ code_section(xml, allergy.codes)
302
+ end
303
+ xml.Status do
304
+ xml.Text("Current")
305
+ end
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end
311
+
312
+ # Builds the XML snippet for a actors section inside the CCR standard
313
+ #
314
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
315
+ def to_ccr_actors(xml, patient)
316
+ xml.Actors do
317
+ xml.Actor do
318
+ xml.ActorObjectID("AA0001")
319
+ xml.Person do
320
+ xml.Name do
321
+ xml.CurrentName do
322
+ xml.Given(patient.first)
323
+ xml.Family(patient.last)
324
+ end
325
+ end
326
+ end
327
+ xml.DateOfBirth do
328
+ xml.ExactDateTime(convert_to_ccr_time_string(patient.birthdate))
329
+ if (patient.gender)
330
+ xml.Gender do
331
+ if (patient.gender.upcase == "M")
332
+ xml.Text("Male")
333
+ elsif (patient.gender.upcase == "F")
334
+ xml.Text("Female")
335
+ else
336
+ xml.Text("Undifferentiated")
337
+ end
338
+ end
339
+ end
340
+ end
341
+ end
342
+ end
343
+ end
344
+
345
+ # Builds the XML snippet for a purpose section inside the CCR standard
346
+ #
347
+ # @return [Builder::XmlMarkup] CCR XML representation of patient data
348
+ def to_ccr_purpose(xml)
349
+ xml.Purpose do
350
+ xml.Description do
351
+ xml.Text("Cypress Test Patient CCR XML Record")
352
+ end
353
+ xml.Indications do
354
+ xml.Indication do
355
+ xml.Source do
356
+ xml.Actor do
357
+ xml.ActorID("AA0002")
358
+ end
359
+ end
360
+ xml.InternalCCRLink do
361
+ xml.LinkID
362
+ end
363
+ end
364
+ end
365
+ end
366
+ end
367
+
368
+ def convert_to_ccr_time_string(time)
369
+ converted_time = Time.at(time)
370
+ converted_time.strftime("%Y-%m-%dT%H:%M:%SZ")
371
+ end
372
+
373
+ end
374
+ end
375
+ end