health-data-standards 0.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.
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