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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +16 -0
  3. data/lib/health-data-standards.rb +3 -0
  4. data/lib/health-data-standards/export/helper/cat1_view_helper.rb +1 -1
  5. data/lib/health-data-standards/export/rendering_context.rb +4 -2
  6. data/lib/health-data-standards/export/template_helper.rb +9 -3
  7. data/lib/health-data-standards/import/bulk_record_importer.rb +88 -0
  8. data/lib/health-data-standards/import/cat1/diagnostic_study_order_importer.rb +1 -1
  9. data/lib/health-data-standards/import/cat1/encounter_performed_importer.rb +38 -0
  10. data/lib/health-data-standards/import/cat1/patient_importer.rb +4 -4
  11. data/lib/health-data-standards/import/cat1/procedure_order_importer.rb +2 -2
  12. data/lib/health-data-standards/import/cat1/procedure_performed_importer.rb +1 -0
  13. data/lib/health-data-standards/import/cda/allergy_importer.rb +0 -2
  14. data/lib/health-data-standards/import/cda/encounter_importer.rb +24 -1
  15. data/lib/health-data-standards/import/cda/medical_equipment_importer.rb +8 -1
  16. data/lib/health-data-standards/import/cda/medication_importer.rb +0 -4
  17. data/lib/health-data-standards/import/cda/procedure_importer.rb +23 -2
  18. data/lib/health-data-standards/import/cda/result_importer.rb +1 -0
  19. data/lib/health-data-standards/import/cda/section_importer.rb +2 -5
  20. data/lib/health-data-standards/import/green_c32/encounter_importer.rb +0 -1
  21. data/lib/health-data-standards/import/green_c32/medication_importer.rb +0 -1
  22. data/lib/health-data-standards/import/green_c32/section_importer.rb +1 -5
  23. data/lib/health-data-standards/import/provider_import_utils.rb +15 -1
  24. data/lib/health-data-standards/models/cqm/aggregate_objects.rb +63 -20
  25. data/lib/health-data-standards/models/cqm/query_cache.rb +3 -26
  26. data/lib/health-data-standards/models/encounter.rb +3 -2
  27. data/lib/health-data-standards/models/entry.rb +8 -1
  28. data/lib/health-data-standards/models/insurance_provider.rb +0 -4
  29. data/lib/health-data-standards/models/provider.rb +10 -0
  30. data/lib/health-data-standards/models/record.rb +31 -8
  31. data/lib/health-data-standards/models/transfer.rb +8 -0
  32. data/templates/cat1/_2.16.840.1.113883.10.20.22.4.85.cat1.erb +1 -0
  33. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.101.cat1.erb +6 -3
  34. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.103.cat1.erb +1 -0
  35. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.12.cat1.erb +1 -0
  36. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.13.cat1.erb +1 -0
  37. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.14.cat1.erb +1 -0
  38. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.2.cat1.erb +1 -3
  39. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.20.cat1.erb +6 -2
  40. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.22.cat1.erb +1 -1
  41. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.23.cat1.erb +21 -0
  42. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.28.cat1.erb +6 -2
  43. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.31.cat1.erb +1 -0
  44. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.32.cat1.erb +1 -0
  45. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.34.cat1.erb +1 -0
  46. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.40.cat1.erb +6 -2
  47. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.46.cat1.erb +1 -0
  48. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.54.cat1.erb +1 -0
  49. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.57.cat1.erb +7 -2
  50. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.59.cat1.erb +5 -1
  51. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.66.cat1.erb +3 -3
  52. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.69.cat1.erb +4 -2
  53. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.7.cat1.erb +1 -1
  54. data/templates/cat3/_continuous_variable_value.cat3.erb +2 -2
  55. data/templates/cat3/_measure_data.cat3.erb +19 -19
  56. data/templates/cat3/_performance_rate.cat3.erb +2 -2
  57. data/templates/cat3/show.cat3.erb +7 -5
  58. data/templates/gc32/_advance_directive.gc32.erb +1 -1
  59. data/templates/gc32/_entry_attributes.gc32.erb +1 -1
  60. data/templates/gc32/_insurance_provider.gc32.erb +2 -2
  61. 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
- eruby = Erubis::EscapedEruby.new(erb) # TODO: cache these
55
- eruby.result(rendering_context.my_binding)
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, '..', '..', '..', 'templates', @template_subdir)
23
+ return File.join(@template_directory, @template_subdir)
24
24
  else
25
- return File.join(@template_directory, '..', '..', '..', 'templates')
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.start_time = HL7Helper.timestamp_to_integer(parent_element.at_xpath("cda:#{element_name}/cda:time")['value'])
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(CDA::ProcedureImporter, "//cda:procedure[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.64']", '2.16.840.1.113883.3.560.1.6'),
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(CDA::EncounterImporter, "//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
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.nil?
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.start_time = HL7Helper.timestamp_to_integer(parent_element.at_xpath("cda:#{element_name}/cda:time")['value'])
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
 
@@ -13,6 +13,7 @@ module HealthDataStandards
13
13
  procedure = super
14
14
  extract_ordinality(entry_element, procedure)
15
15
  extract_incision_date_time(entry_element,procedure)
16
+ extract_negation(entry_element, procedure)
16
17
  procedure
17
18
  end
18
19
 
@@ -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
- extract_description(reason_element, reason, nrh)
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 extract_anatomical_structure(entry_element, entry)
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 = nil
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