health-data-standards 3.3.0 → 3.4.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.
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