health-data-standards 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +16 -0
- data/lib/health-data-standards.rb +3 -0
- data/lib/health-data-standards/export/helper/cat1_view_helper.rb +1 -1
- data/lib/health-data-standards/export/rendering_context.rb +4 -2
- data/lib/health-data-standards/export/template_helper.rb +9 -3
- data/lib/health-data-standards/import/bulk_record_importer.rb +88 -0
- data/lib/health-data-standards/import/cat1/diagnostic_study_order_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/encounter_performed_importer.rb +38 -0
- data/lib/health-data-standards/import/cat1/patient_importer.rb +4 -4
- data/lib/health-data-standards/import/cat1/procedure_order_importer.rb +2 -2
- data/lib/health-data-standards/import/cat1/procedure_performed_importer.rb +1 -0
- data/lib/health-data-standards/import/cda/allergy_importer.rb +0 -2
- data/lib/health-data-standards/import/cda/encounter_importer.rb +24 -1
- data/lib/health-data-standards/import/cda/medical_equipment_importer.rb +8 -1
- data/lib/health-data-standards/import/cda/medication_importer.rb +0 -4
- data/lib/health-data-standards/import/cda/procedure_importer.rb +23 -2
- data/lib/health-data-standards/import/cda/result_importer.rb +1 -0
- data/lib/health-data-standards/import/cda/section_importer.rb +2 -5
- data/lib/health-data-standards/import/green_c32/encounter_importer.rb +0 -1
- data/lib/health-data-standards/import/green_c32/medication_importer.rb +0 -1
- data/lib/health-data-standards/import/green_c32/section_importer.rb +1 -5
- data/lib/health-data-standards/import/provider_import_utils.rb +15 -1
- data/lib/health-data-standards/models/cqm/aggregate_objects.rb +63 -20
- data/lib/health-data-standards/models/cqm/query_cache.rb +3 -26
- data/lib/health-data-standards/models/encounter.rb +3 -2
- data/lib/health-data-standards/models/entry.rb +8 -1
- data/lib/health-data-standards/models/insurance_provider.rb +0 -4
- data/lib/health-data-standards/models/provider.rb +10 -0
- data/lib/health-data-standards/models/record.rb +31 -8
- data/lib/health-data-standards/models/transfer.rb +8 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.22.4.85.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.101.cat1.erb +6 -3
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.103.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.12.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.13.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.14.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.2.cat1.erb +1 -3
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.20.cat1.erb +6 -2
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.22.cat1.erb +1 -1
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.23.cat1.erb +21 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.28.cat1.erb +6 -2
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.31.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.32.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.34.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.40.cat1.erb +6 -2
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.46.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.54.cat1.erb +1 -0
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.57.cat1.erb +7 -2
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.59.cat1.erb +5 -1
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.66.cat1.erb +3 -3
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.69.cat1.erb +4 -2
- data/templates/cat1/_2.16.840.1.113883.10.20.24.3.7.cat1.erb +1 -1
- data/templates/cat3/_continuous_variable_value.cat3.erb +2 -2
- data/templates/cat3/_measure_data.cat3.erb +19 -19
- data/templates/cat3/_performance_rate.cat3.erb +2 -2
- data/templates/cat3/show.cat3.erb +7 -5
- data/templates/gc32/_advance_directive.gc32.erb +1 -1
- data/templates/gc32/_entry_attributes.gc32.erb +1 -1
- data/templates/gc32/_insurance_provider.gc32.erb +2 -2
- metadata +10 -29
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ad62ad18c9fe2cd1dcd360ee1470fa366c1b6a17
|
4
|
+
data.tar.gz: 93fc2151c1654a38fb0fbb0d550cddde76773079
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3cd6ed227cb200fb8219d00f11144adaf6b4870842d1758aff1be230e151287b5612774f221e011d6efbe52e08f0aa16bb4e26d4b4f77699a8e4ee6ffd160281
|
7
|
+
data.tar.gz: 7a4f8b8d108a0e9e67b09830d557f797d7c2ec4acf249aeac8aec9c3c843a16abf2a77e3a4c97f5457dcbd1c8946135c504881924a83db61f60c952ef74d274f
|
data/README.md
CHANGED
@@ -25,6 +25,22 @@ Please try to follow the [GitHub Coding Style Guides](https://github.com/stylegu
|
|
25
25
|
Change Log
|
26
26
|
==========
|
27
27
|
|
28
|
+
3.4.0 - January 23, 2014
|
29
|
+
|
30
|
+
* _New Feature_ - BulkRecordImporter class now available that provides the ability to import QRDA Cat I, Consolidated CDA and HITSP C32
|
31
|
+
* TemplateHelper now properly accepts a different directory for templates
|
32
|
+
* QRDA Cat I importer now extracts negation on procedures
|
33
|
+
* Implemented support to encounter transfers in QRDA Cat I import and export
|
34
|
+
* Fixed bug where clinical trial participant would always return true on Record
|
35
|
+
* QRDA Cat I importer now extracts ordinality and values from procedures
|
36
|
+
* Better de-duplicating of data elements imported from QRDA Cat I
|
37
|
+
* CDA importers now handle removal time on medical equipment
|
38
|
+
* QRDA Cat I exporter now handles 38 week gestational period
|
39
|
+
* Stratification fixes for QRDA Cat III export
|
40
|
+
* QRDA Cat I importer now extracts incision date/time from procedure performed templates
|
41
|
+
* CDA importers set admit times on encounters
|
42
|
+
* QRDA Cat I diagnostic study order and procedure order importer now better handles order time for CQM calculation
|
43
|
+
|
28
44
|
3.3.0 - November 7, 2013
|
29
45
|
|
30
46
|
* Removing hardcoded headers in QRDA documents and replacing them with templates populated by Ruby objects
|
@@ -65,6 +65,7 @@ require_relative 'health-data-standards/models/person'
|
|
65
65
|
require_relative 'health-data-standards/models/organization'
|
66
66
|
require_relative 'health-data-standards/models/address'
|
67
67
|
require_relative 'health-data-standards/models/telecom'
|
68
|
+
require_relative 'health-data-standards/models/transfer'
|
68
69
|
require_relative 'health-data-standards/models/svs/value_set'
|
69
70
|
require_relative 'health-data-standards/models/svs/concept'
|
70
71
|
require_relative 'health-data-standards/models/facility'
|
@@ -164,6 +165,7 @@ require_relative 'health-data-standards/import/cat1/lab_order_importer'
|
|
164
165
|
require_relative 'health-data-standards/import/cat1/medication_active_importer'
|
165
166
|
require_relative 'health-data-standards/import/cat1/medication_dispensed_importer'
|
166
167
|
require_relative 'health-data-standards/import/cat1/encounter_order_importer'
|
168
|
+
require_relative 'health-data-standards/import/cat1/encounter_performed_importer'
|
167
169
|
require_relative 'health-data-standards/import/cat1/diagnostic_study_order_importer'
|
168
170
|
require_relative 'health-data-standards/import/cat1/tobacco_use_importer'
|
169
171
|
require_relative 'health-data-standards/import/cat1/entry_package'
|
@@ -174,6 +176,7 @@ require_relative 'health-data-standards/import/cat1/insurance_provider_importer'
|
|
174
176
|
|
175
177
|
require_relative 'health-data-standards/import/bundle/importer'
|
176
178
|
|
179
|
+
require_relative 'health-data-standards/import/bulk_record_importer'
|
177
180
|
|
178
181
|
module HealthDataStandards
|
179
182
|
class << self
|
@@ -41,7 +41,7 @@ module HealthDataStandards
|
|
41
41
|
return nil if codedValue.nil?
|
42
42
|
valueset_oids ||=[]
|
43
43
|
code = codedValue["code"]
|
44
|
-
code_system = codedValue["code_set"]
|
44
|
+
code_system = codedValue["code_set"] || codedValue["code_system"]
|
45
45
|
vs_map = (value_set_map(bundle_id) || {})
|
46
46
|
valueset_oids.each do |vs_oid|
|
47
47
|
oid_list = (vs_map[vs_oid] || [])
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module HealthDataStandards
|
2
2
|
module Export
|
3
|
+
|
3
4
|
# Used to actually render stuff. A RenderingContext needs to be set up with
|
4
5
|
# a template helper and may be provided with extensions.
|
5
6
|
#
|
@@ -51,8 +52,9 @@ module HealthDataStandards
|
|
51
52
|
rendering_context.extend(extension)
|
52
53
|
end
|
53
54
|
end
|
54
|
-
|
55
|
-
|
55
|
+
eruby = Erubis::EscapedEruby.new(erb) # TODO: cache these
|
56
|
+
eruby.filename= @template_helper.template_file((params[:template] || params[:partial]), params[:partial]).path
|
57
|
+
eruby.result(rendering_context.my_binding)
|
56
58
|
end.join
|
57
59
|
end
|
58
60
|
end
|
@@ -17,12 +17,12 @@ module HealthDataStandards
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def template_root
|
20
|
-
@template_directory ||= File.dirname(__FILE__)
|
20
|
+
@template_directory ||= File.join(File.dirname(__FILE__), '..', '..', '..', 'templates')
|
21
21
|
|
22
22
|
if @template_subdir
|
23
|
-
return File.join(@template_directory,
|
23
|
+
return File.join(@template_directory, @template_subdir)
|
24
24
|
else
|
25
|
-
return
|
25
|
+
return @template_directory
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -37,6 +37,12 @@ module HealthDataStandards
|
|
37
37
|
def partial(partial_name)
|
38
38
|
template("_#{partial_name}")
|
39
39
|
end
|
40
|
+
|
41
|
+
def template_file(file,partial=false)
|
42
|
+
file = partial ? "_#{file}" : file
|
43
|
+
File.new(File.join(template_root, "#{file}.#{@template_format}.erb"))
|
44
|
+
end
|
45
|
+
|
40
46
|
end
|
41
47
|
end
|
42
48
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
module HealthDataStandards
|
3
|
+
module Import
|
4
|
+
class BulkRecordImporter
|
5
|
+
|
6
|
+
def self.import_directory(source_dir)
|
7
|
+
|
8
|
+
xml_files = Dir.glob(File.join(source_dir, '*.*'))
|
9
|
+
xml_files.each do |file|
|
10
|
+
begin
|
11
|
+
|
12
|
+
result = RecordImporter.import(File.new(file).read, provider_map)
|
13
|
+
|
14
|
+
if (result[:status] == 'success')
|
15
|
+
record = result[:record]
|
16
|
+
record.save
|
17
|
+
else
|
18
|
+
assert result[:message]
|
19
|
+
end
|
20
|
+
|
21
|
+
rescue Exception => e
|
22
|
+
failed_dir = File.join(source_dir, '../', 'failed_imports')
|
23
|
+
unless(Dir.exists?(failed_dir))
|
24
|
+
Dir.mkdir(failed_dir)
|
25
|
+
end
|
26
|
+
FileUtils.cp(file, failed_dir)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.import_archive(file)
|
32
|
+
Zip::ZipFile.open(file.path) do |zipfile|
|
33
|
+
zipfile.entries.each do |entry|
|
34
|
+
next if entry.directory?
|
35
|
+
xml = zipfile.read(entry.name)
|
36
|
+
begin
|
37
|
+
BulkRecordImporter.import(xml)
|
38
|
+
rescue Exception => e
|
39
|
+
failed_dir = File.join(file.dirname, 'failed_imports')
|
40
|
+
unless(Dir.exists?(failed_dir))
|
41
|
+
Dir.mkdir(failed_dir)
|
42
|
+
end
|
43
|
+
FileUtils.cp(file, failed_dir)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.import(xml_data, provider_map = {})
|
50
|
+
doc = Nokogiri::XML(xml_data)
|
51
|
+
|
52
|
+
providers = []
|
53
|
+
root_element_name = doc.root.name
|
54
|
+
|
55
|
+
if root_element_name == 'ClinicalDocument'
|
56
|
+
doc.root.add_namespace_definition('cda', 'urn:hl7-org:v3')
|
57
|
+
doc.root.add_namespace_definition('sdtc', 'urn:hl7-org:sdtc')
|
58
|
+
|
59
|
+
if doc.at_xpath("/cda:ClinicalDocument/cda:templateId[@root='2.16.840.1.113883.3.88.11.32.1']")
|
60
|
+
patient_data = C32::PatientImporter.instance.parse_c32(doc)
|
61
|
+
elsif doc.at_xpath("/cda:ClinicalDocument/cda:templateId[@root='2.16.840.1.113883.10.20.22.1.2']")
|
62
|
+
patient_data = CCDA::PatientImporter.instance.parse_ccda(doc)
|
63
|
+
elsif doc.at_xpath("/cda:ClinicalDocument/cda:templateId[@root='2.16.840.1.113883.10.20.24.1.2']")
|
64
|
+
patient_data = Cat1::PatientImporter.instance.parse_cat1(doc)
|
65
|
+
else
|
66
|
+
STDERR.puts("Unable to determinate document template/type of CDA document")
|
67
|
+
return {status: 'error', message: "Document templateId does not identify it as a C32 or CCDA", status_code: 400}
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
providers = CDA::ProviderImporter.instance.extract_providers(doc)
|
72
|
+
rescue Exception => e
|
73
|
+
STDERR.puts "error extracting providers"
|
74
|
+
end
|
75
|
+
else
|
76
|
+
return {status: 'error', message: 'Unknown XML Format', status_code: 400}
|
77
|
+
end
|
78
|
+
|
79
|
+
record = Record.update_or_create(patient_data)
|
80
|
+
record.provider_performances = providers
|
81
|
+
record.save
|
82
|
+
|
83
|
+
{status: 'success', message: 'patient imported', status_code: 201, record: record}
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -11,7 +11,7 @@ module HealthDataStandards
|
|
11
11
|
|
12
12
|
def extract_dates(parent_element, entry, element_name="author")
|
13
13
|
if parent_element.at_xpath("cda:#{element_name}/cda:time/@value")
|
14
|
-
entry.
|
14
|
+
entry.time = HL7Helper.timestamp_to_integer(parent_element.at_xpath("cda:#{element_name}/cda:time")['value'])
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module HealthDataStandards
|
2
|
+
module Import
|
3
|
+
module Cat1
|
4
|
+
class EncounterPerformedImporter < CDA::EncounterImporter
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("//cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.23']"))
|
6
|
+
super(entry_finder)
|
7
|
+
@reason_xpath = "./cda:entryRelationship[@typeCode='RSON']/cda:observation"
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
11
|
+
encounter = super
|
12
|
+
extract_admit_time(entry_element, encounter)
|
13
|
+
extract_reason(entry_element, encounter, nrh)
|
14
|
+
encounter
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def extract_reason(parent_element, encounter, nrh)
|
20
|
+
reason_element = parent_element.at_xpath(@reason_xpath)
|
21
|
+
if reason_element
|
22
|
+
reason = Entry.new
|
23
|
+
extract_codes(reason_element, reason)
|
24
|
+
extract_reason_description(reason_element, reason, nrh)
|
25
|
+
extract_status(reason_element, reason)
|
26
|
+
extract_dates(reason_element, reason)
|
27
|
+
encounter.reason = reason
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def extract_admit_time(parent_element, encounter)
|
32
|
+
encounter.admit_time = encounter.start_time
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -38,7 +38,7 @@ module HealthDataStandards
|
|
38
38
|
generate_importer(CDA::ProcedureImporter, "//cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.4']", '2.16.840.1.113883.3.560.1.129'), #comm from provider to provider
|
39
39
|
generate_importer(CDA::ProcedureImporter, "//cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.2']", '2.16.840.1.113883.3.560.1.30'), #comm from patient to provider
|
40
40
|
generate_importer(ProcedureOrderImporter, nil, '2.16.840.1.113883.3.560.1.62', 'ordered'),
|
41
|
-
generate_importer(
|
41
|
+
generate_importer(ProcedurePerformedImporter, "//cda:procedure[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.64']", '2.16.840.1.113883.3.560.1.6'),
|
42
42
|
generate_importer(CDA::ProcedureImporter, "//cda:procedure[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.66']", '2.16.840.1.113883.3.560.1.63'),
|
43
43
|
generate_importer(CDA::ProcedureImporter, "//cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.69']", '2.16.840.1.113883.3.560.1.21'),
|
44
44
|
generate_importer(CDA::ProcedureImporter, "//cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.18']", '2.16.840.1.113883.3.560.1.103', 'performed'), #diagnostic study performed
|
@@ -59,7 +59,7 @@ module HealthDataStandards
|
|
59
59
|
generate_importer(CDA::ResultImporter, "//cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.20']", '2.16.840.1.113883.3.560.1.111'), #diagnostic study result not done
|
60
60
|
generate_importer(LabResultImporter, nil, '2.16.840.1.113883.3.560.1.12')] #lab result
|
61
61
|
|
62
|
-
@section_importers[:encounters] = [generate_importer(
|
62
|
+
@section_importers[:encounters] = [generate_importer(EncounterPerformedImporter, "//cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.23']", '2.16.840.1.113883.3.560.1.79', 'performed'), #encounter performed
|
63
63
|
generate_importer(EncounterOrderImporter, nil, '2.16.840.1.113883.3.560.1.83', 'ordered')]
|
64
64
|
|
65
65
|
@section_importers[:social_history] = [generate_importer(TobaccoUseImporter, nil, '2.16.840.1.113883.3.560.1.1001', 'completed')]
|
@@ -90,7 +90,7 @@ module HealthDataStandards
|
|
90
90
|
|
91
91
|
def get_clinical_trial_participant(record, doc)
|
92
92
|
entry_elements = doc.xpath("//cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.51']")
|
93
|
-
record.clinicalTrialParticipant = true unless entry_elements.
|
93
|
+
record.clinicalTrialParticipant = true unless entry_elements.blank?
|
94
94
|
end
|
95
95
|
|
96
96
|
def get_patient_expired(record, doc)
|
@@ -111,4 +111,4 @@ module HealthDataStandards
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
114
|
-
end
|
114
|
+
end
|
@@ -6,7 +6,7 @@ module HealthDataStandards
|
|
6
6
|
super(entry_finder)
|
7
7
|
@entry_class = Procedure
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def create_entry(entry_element, nrh = CDA::NarrativeReferenceHandler.new)
|
11
11
|
procedure = super
|
12
12
|
procedure.status_code = {'HL7 ActStatus' => ['ordered']}
|
@@ -20,7 +20,7 @@ module HealthDataStandards
|
|
20
20
|
|
21
21
|
def extract_dates(parent_element, entry, element_name="author")
|
22
22
|
if parent_element.at_xpath("cda:#{element_name}/cda:time/@value")
|
23
|
-
entry.
|
23
|
+
entry.time = HL7Helper.timestamp_to_integer(parent_element.at_xpath("cda:#{element_name}/cda:time")['value'])
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -8,7 +8,6 @@ module HealthDataStandards
|
|
8
8
|
@code_xpath = "./cda:participant/cda:participantRole/cda:playingEntity/cda:code"
|
9
9
|
@description_xpath = "./cda:code/cda:originalText/cda:reference[@value] | ./cda:text/cda:reference[@value]"
|
10
10
|
@type_xpath = "./cda:code"
|
11
|
-
@free_text_xpath= "./cda:participant/cda:participantRole/cda:playingEntity/cda:name"
|
12
11
|
@reaction_xpath = "./cda:entryRelationship[@typeCode='MFST']/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.1.54']/cda:value"
|
13
12
|
@severity_xpath = "./cda:entryRelationship[@typeCode='SUBJ']/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.1.55']/cda:value"
|
14
13
|
@status_xpath = "./cda:entryRelationship[@typeCode='REFR']/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.1.39']/cda:value"
|
@@ -17,7 +16,6 @@ module HealthDataStandards
|
|
17
16
|
|
18
17
|
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
19
18
|
allergy = super
|
20
|
-
allergy.free_text = entry_element.at_xpath(@free_text_xpath).try(:text)
|
21
19
|
extract_negation(entry_element, allergy)
|
22
20
|
allergy.type = extract_code(entry_element, @type_xpath)
|
23
21
|
allergy.reaction = extract_code(entry_element, @reaction_xpath)
|
@@ -18,6 +18,7 @@ module HealthDataStandards
|
|
18
18
|
extract_negation(entry_element, encounter)
|
19
19
|
extract_admission(entry_element, encounter)
|
20
20
|
extract_discharge_disposition(entry_element, encounter)
|
21
|
+
extract_transfers(entry_element, encounter)
|
21
22
|
encounter
|
22
23
|
end
|
23
24
|
|
@@ -45,7 +46,7 @@ module HealthDataStandards
|
|
45
46
|
if reason_element
|
46
47
|
reason = Entry.new
|
47
48
|
extract_codes(reason_element, reason)
|
48
|
-
|
49
|
+
extract_reason_description(reason_element, reason, nrh)
|
49
50
|
extract_status(reason_element, reason)
|
50
51
|
extract_dates(reason_element, reason)
|
51
52
|
encounter.reason = reason
|
@@ -60,6 +61,28 @@ module HealthDataStandards
|
|
60
61
|
encounter.discharge_time = encounter.end_time
|
61
62
|
encounter.discharge_disposition = extract_code(parent_element, "./sdtc:dischargeDispositionCode")
|
62
63
|
end
|
64
|
+
|
65
|
+
def extract_transfers(parent_element, encounter)
|
66
|
+
transfer_from_element = parent_element.at_xpath("./cda:participant[@typeCode='ORG']")
|
67
|
+
if (transfer_from_element)
|
68
|
+
transfer_from = Transfer.new(time: transfer_from_element.at_xpath("./cda:time")['value'])
|
69
|
+
transfer_from_subelement = transfer_from_element.at_xpath("./cda:participantRole[@classCode='LOCE']")
|
70
|
+
raw_tf_code = extract_code(transfer_from_subelement, './cda:code')
|
71
|
+
code_hash = {CodeSystemHelper.code_system_for(raw_tf_code["codeSystemOid"]) => [raw_tf_code["code"]]}
|
72
|
+
transfer_from.codes = code_hash
|
73
|
+
encounter.transfer_from = transfer_from
|
74
|
+
end
|
75
|
+
|
76
|
+
transfer_to_element = parent_element.at_xpath("./cda:participant[@typeCode='DST']")
|
77
|
+
if (transfer_to_element)
|
78
|
+
transfer_to = Transfer.new(time: transfer_to_element.at_xpath("./cda:time")['value'])
|
79
|
+
transfer_to_subelement = transfer_to_element.at_xpath("./cda:participantRole[@classCode='LOCE']")
|
80
|
+
raw_tt_code = extract_code(transfer_to_subelement, './cda:code')
|
81
|
+
code_hash = {CodeSystemHelper.code_system_for(raw_tt_code["codeSystemOid"]) => [raw_tt_code["code"]]}
|
82
|
+
transfer_to.codes = code_hash
|
83
|
+
encounter.transfer_to = transfer_to
|
84
|
+
end
|
85
|
+
end
|
63
86
|
end
|
64
87
|
end
|
65
88
|
end
|
@@ -13,6 +13,7 @@ module HealthDataStandards
|
|
13
13
|
medical_equipment = super
|
14
14
|
extract_manufacturer(entry_element, medical_equipment)
|
15
15
|
extract_anatomical_structure(entry_element, medical_equipment)
|
16
|
+
extract_removal_time(entry_element, medical_equipment)
|
16
17
|
medical_equipment
|
17
18
|
end
|
18
19
|
|
@@ -21,7 +22,13 @@ module HealthDataStandards
|
|
21
22
|
entry.manufacturer = manufacturer.strip if manufacturer
|
22
23
|
end
|
23
24
|
|
24
|
-
def
|
25
|
+
def extract_removal_time(entry_element, entry)
|
26
|
+
if entry_element.at_xpath("cda:effectiveTime/cda:high")
|
27
|
+
entry.removal_time = HL7Helper.timestamp_to_integer(entry_element.at_xpath("cda:effectiveTime/cda:high")['value'])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def extract_anatomical_structure(entry_element, entry)
|
25
32
|
site = entry_element.at_xpath(@anatomical_xpath)
|
26
33
|
if site
|
27
34
|
entry.anatomical_structure = {CodeSystemHelper.code_system_for(site['codeSystem']) => [site['code']]}
|
@@ -25,10 +25,6 @@ module HealthDataStandards
|
|
25
25
|
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
26
26
|
medication = super
|
27
27
|
|
28
|
-
if medication.description.present?
|
29
|
-
medication.free_text = medication.description
|
30
|
-
end
|
31
|
-
|
32
28
|
extract_administration_timing(entry_element, medication)
|
33
29
|
|
34
30
|
medication.route = extract_code(entry_element, "./cda:routeCode")
|
@@ -8,19 +8,29 @@ module HealthDataStandards
|
|
8
8
|
def initialize(entry_finder=EntryFinder.new("//cda:section[cda:templateId/@root!='2.16.840.1.113883.3.88.11.83.124']//cda:procedure"))
|
9
9
|
super(entry_finder)
|
10
10
|
@entry_class = Procedure
|
11
|
-
@value_xpath =
|
11
|
+
@value_xpath = ".//cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.87']/cda:value"
|
12
|
+
@ordinality_xpath = "./cda:priorityCode"
|
12
13
|
end
|
13
|
-
|
14
|
+
|
14
15
|
def create_entry(entry_element, nrh = NarrativeReferenceHandler.new)
|
15
16
|
procedure = super
|
17
|
+
extract_ordinality(entry_element, procedure)
|
16
18
|
extract_performer(entry_element, procedure)
|
17
19
|
extract_site(entry_element, procedure)
|
18
20
|
extract_negation(entry_element, procedure)
|
21
|
+
extract_scalar(entry_element, procedure)
|
19
22
|
procedure
|
20
23
|
end
|
21
24
|
|
22
25
|
private
|
23
26
|
|
27
|
+
def extract_ordinality(parent_element, procedure)
|
28
|
+
ordinality_element = parent_element.at_xpath(@ordinality_xpath)
|
29
|
+
if ordinality_element
|
30
|
+
procedure.ordinality = {CodeSystemHelper.code_system_for(ordinality_element['codeSystem']) => [ordinality_element['code']]}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
24
34
|
def extract_performer(parent_element, procedure)
|
25
35
|
performer_element = parent_element.at_xpath("./cda:performer")
|
26
36
|
procedure.performer = import_actor(performer_element) if performer_element
|
@@ -30,6 +40,17 @@ module HealthDataStandards
|
|
30
40
|
procedure.site = extract_code(parent_element, "./cda:targetSiteCode")
|
31
41
|
end
|
32
42
|
|
43
|
+
def extract_scalar(parent_element, procedure)
|
44
|
+
return unless scalar_element = parent_element.at_xpath("./cda:value")
|
45
|
+
case scalar_element["xsi:type"]
|
46
|
+
when "PQ"
|
47
|
+
procedure.set_value scalar_element['value'].to_i, scalar_element['unit']
|
48
|
+
when "BL"
|
49
|
+
procedure.set_value scalar_element['value']
|
50
|
+
when "ST"
|
51
|
+
procedure.set_value scalar_element.content
|
52
|
+
end
|
53
|
+
end
|
33
54
|
end
|
34
55
|
end
|
35
56
|
end
|