health-data-standards 1.0.1 → 2.0.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 (50) hide show
  1. data/Gemfile +5 -5
  2. data/lib/health-data-standards.rb +8 -0
  3. data/lib/health-data-standards/export/ccda.rb +15 -0
  4. data/lib/health-data-standards/export/ccr.rb +24 -20
  5. data/lib/health-data-standards/export/html.rb +4 -8
  6. data/lib/health-data-standards/export/template_helper.rb +7 -1
  7. data/lib/health-data-standards/export/view_helper.rb +24 -4
  8. data/lib/health-data-standards/import/c32/allergy_importer.rb +2 -1
  9. data/lib/health-data-standards/import/c32/care_goal_importer.rb +2 -1
  10. data/lib/health-data-standards/import/c32/condition_importer.rb +23 -2
  11. data/lib/health-data-standards/import/c32/encounter_importer.rb +6 -5
  12. data/lib/health-data-standards/import/c32/immunization_importer.rb +1 -15
  13. data/lib/health-data-standards/import/c32/medication_importer.rb +1 -0
  14. data/lib/health-data-standards/import/c32/patient_importer.rb +13 -0
  15. data/lib/health-data-standards/import/c32/procedure_importer.rb +1 -0
  16. data/lib/health-data-standards/import/c32/provider_importer.rb +1 -1
  17. data/lib/health-data-standards/import/c32/result_importer.rb +1 -0
  18. data/lib/health-data-standards/import/c32/section_importer.rb +17 -22
  19. data/lib/health-data-standards/import/ccda/medical_equipment_importer.rb +1 -2
  20. data/lib/health-data-standards/import/ccda/result_importer.rb +1 -0
  21. data/lib/health-data-standards/import/ccr/provider_importer.rb +0 -1
  22. data/lib/health-data-standards/import/green_c32/immunization_importer.rb +1 -1
  23. data/lib/health-data-standards/import/green_c32/section_importer.rb +7 -5
  24. data/lib/health-data-standards/import/provider_import_utils.rb +1 -1
  25. data/lib/health-data-standards/models/coded_result_value.rb +3 -0
  26. data/lib/health-data-standards/models/condition.rb +7 -5
  27. data/lib/health-data-standards/models/encounter.rb +5 -2
  28. data/lib/health-data-standards/models/entry.rb +48 -68
  29. data/lib/health-data-standards/models/facility.rb +9 -0
  30. data/lib/health-data-standards/models/functional_status.rb +25 -0
  31. data/lib/health-data-standards/models/immunization.rb +4 -6
  32. data/lib/health-data-standards/models/medication.rb +6 -0
  33. data/lib/health-data-standards/models/physical_quantity_result_value.rb +4 -0
  34. data/lib/health-data-standards/models/record.rb +11 -2
  35. data/lib/health-data-standards/models/result_value.rb +4 -0
  36. data/lib/health-data-standards/models/thing_with_codes.rb +52 -0
  37. data/lib/health-data-standards/util/code_system_helper.rb +5 -2
  38. data/lib/health-data-standards/util/qrda_template_helper.rb +20 -0
  39. data/templates/_allergies_no_current.c32.erb +26 -4
  40. data/templates/_conditions_no_current.c32.erb +1 -2
  41. data/templates/_medications_no_current.c32.erb +1 -1
  42. data/templates/_narrative_block.c32.erb +14 -2
  43. data/templates/_result.gc32.erb +3 -1
  44. data/templates/_results.c32.erb +9 -8
  45. data/templates/_social_history.gc32.erb +1 -1
  46. data/templates/_vital_sign.gc32.erb +1 -1
  47. data/templates/_vital_signs.c32.erb +12 -11
  48. data/templates/show.c32.erb +1 -1
  49. metadata +55 -21
  50. data/templates/show.html.erb +0 -287
data/Gemfile CHANGED
@@ -4,14 +4,14 @@ gemspec :development_group => :test
4
4
 
5
5
  group :development do
6
6
  gem 'rake'
7
- gem 'pry'
8
- gem 'pry-nav'
7
+ gem 'pry', '~> 0.9.10'
8
+ gem 'pry-nav', '~> 0.2.2'
9
9
 
10
10
  end
11
11
 
12
12
  group :test do
13
- gem 'factory_girl'
14
- gem "tailor"
15
- gem "cane"
13
+ gem 'factory_girl', '~> 4.1.0'
14
+ gem "tailor", '~> 1.1.2'
15
+ gem "cane", '~> 2.3.0'
16
16
  gem 'simplecov', :require => false
17
17
  end
@@ -12,11 +12,13 @@ require_relative 'health-data-standards/ext/string'
12
12
 
13
13
  require_relative 'health-data-standards/util/hl7_helper'
14
14
  require_relative 'health-data-standards/util/code_system_helper'
15
+ require_relative 'health-data-standards/util/qrda_template_helper'
15
16
 
16
17
  require_relative 'health-data-standards/export/template_helper'
17
18
  require_relative 'health-data-standards/export/view_helper'
18
19
  require_relative 'health-data-standards/export/rendering_context'
19
20
  require_relative 'health-data-standards/export/c32'
21
+ require_relative 'health-data-standards/export/ccda'
20
22
  require_relative 'health-data-standards/export/ccr'
21
23
  require_relative 'health-data-standards/export/csv'
22
24
  require_relative 'health-data-standards/export/html'
@@ -29,6 +31,10 @@ require_relative 'health-data-standards/export/green_c32/export_generator'
29
31
  require_relative 'health-data-standards/import/provider_import_utils'
30
32
  require_relative 'health-data-standards/import/hdata/metadata_importer'
31
33
 
34
+ require_relative 'health-data-standards/models/thing_with_codes'
35
+ require_relative 'health-data-standards/models/result_value'
36
+ require_relative 'health-data-standards/models/coded_result_value'
37
+ require_relative 'health-data-standards/models/physical_quantity_result_value'
32
38
  require_relative 'health-data-standards/models/entry'
33
39
  require_relative 'health-data-standards/models/allergy'
34
40
  require_relative 'health-data-standards/models/encounter'
@@ -39,6 +45,7 @@ require_relative 'health-data-standards/models/order_information'
39
45
  require_relative 'health-data-standards/models/medication'
40
46
  require_relative 'health-data-standards/models/procedure'
41
47
  require_relative 'health-data-standards/models/lab_result'
48
+ require_relative 'health-data-standards/models/functional_status'
42
49
  require_relative 'health-data-standards/models/medical_equipment'
43
50
  require_relative 'health-data-standards/models/record'
44
51
  require_relative 'health-data-standards/models/personable'
@@ -52,6 +59,7 @@ require_relative 'health-data-standards/models/person'
52
59
  require_relative 'health-data-standards/models/organization'
53
60
  require_relative 'health-data-standards/models/address'
54
61
  require_relative 'health-data-standards/models/telecom'
62
+ require_relative 'health-data-standards/models/facility'
55
63
  require_relative 'health-data-standards/models/metadata/base'
56
64
  require_relative 'health-data-standards/models/metadata/author'
57
65
  require_relative 'health-data-standards/models/metadata/change_info'
@@ -0,0 +1,15 @@
1
+ module HealthDataStandards
2
+ module Export
3
+ module CCDA
4
+ include TemplateHelper
5
+
6
+ def export(patient)
7
+ self.template_format = "ccda"
8
+ self.template_subdir = "ccda"
9
+ render(:template => 'show', :locals => {:patient => patient})
10
+ end
11
+
12
+ extend self
13
+ end
14
+ end
15
+ end
@@ -149,29 +149,33 @@ module HealthDataStandards
149
149
  end
150
150
 
151
151
 
152
- def to_result(xml, res, ccr_id )
153
- xml.Result do
154
- xml.CCRDataObjectID(ccr_id)
155
- to_ccr_date(xml, res.as_point_in_time, "Start date")
156
- xml.Source
157
- xml.Test do
158
- xml.CCRDataObjectID("#{ccr_id}TestResult")
159
- xml.Description do
152
+ def to_result(xml, res, ccr_id )
153
+ xml.Result do
154
+ xml.CCRDataObjectID(ccr_id)
155
+ to_ccr_date(xml, res.as_point_in_time, "Start date")
156
+ xml.Source
157
+ xml.Test do
158
+ xml.CCRDataObjectID("#{ccr_id}TestResult")
159
+ xml.Description do
160
160
  xml.Text(res.description)
161
161
  code_section(xml, res.codes)
162
- end
162
+ end
163
163
 
164
- xml.Source
165
- xml.TestResult do
166
- xml.Value(res.value["scalar"])
167
- xml.Units do
168
- xml.Unit(res.value["units"])
169
- end
170
- end
171
- end
172
- end
173
-
174
- end
164
+ xml.Source
165
+ xml.TestResult do
166
+ rv = res.values.first
167
+ if rv.present? && rv.respond_to?(:scalar)
168
+ xml.Value(rv.scalar)
169
+ xml.Unit do
170
+ xml.Unit(rv.units)
171
+ end
172
+ else
173
+
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
175
179
 
176
180
  # Builds the XML snippet for the medications section inside the CCR standard
177
181
  #
@@ -3,19 +3,15 @@ module HealthDataStandards
3
3
  module HTML
4
4
  include TemplateHelper
5
5
 
6
- def export(patient)
6
+ def export(patient)
7
7
  self.template_format = "html"
8
+ self.template_subdir = "html"
8
9
  render(:template => 'show', :locals => {:patient => patient})
9
10
  end
10
11
 
11
12
  extend self
12
-
13
-
14
-
15
-
16
-
17
-
18
-
13
+
14
+
19
15
  end
20
16
  end
21
17
  end
@@ -2,9 +2,14 @@ module HealthDataStandards
2
2
  module Export
3
3
  module TemplateHelper
4
4
  attr_accessor :template_format
5
+ attr_accessor :template_subdir
5
6
 
6
7
  def template_root
7
- File.join(File.dirname(__FILE__), '..', '..', '..', 'templates')
8
+ if @template_subdir
9
+ return File.join(File.dirname(__FILE__), '..', '..', '..', 'templates', @template_subdir)
10
+ else
11
+ return File.join(File.dirname(__FILE__), '..', '..', '..', 'templates')
12
+ end
8
13
  end
9
14
 
10
15
  def template(template_name)
@@ -27,6 +32,7 @@ module HealthDataStandards
27
32
  locals ||= {}
28
33
  rendering_context = RenderingContext.new(locals)
29
34
  rendering_context.template_format = self.template_format
35
+ rendering_context.template_subdir = self.template_subdir
30
36
  eruby = Erubis::EscapedEruby.new(erb)
31
37
  eruby.result(rendering_context.my_binding)
32
38
  end
@@ -27,11 +27,11 @@ module HealthDataStandards
27
27
 
28
28
  def gc32_effective_time(entry)
29
29
  if entry.time
30
- "<effectiveTime value=\"#{Time.at(entry.time)}\" />"
30
+ "<effectiveTime value=\"#{Time.at(entry.time).to_formatted_s(:number)}\" />"
31
31
  elsif entry.start_time || entry.end_time
32
32
  time = "<effectiveTime>"
33
- time += "<start value=\"#{Time.at(entry.start_time)}\" />" if entry.start_time
34
- time += "<end value=\"#{Time.at(entry.end_time)}\" />" if entry.end_time
33
+ time += "<start value=\"#{Time.at(entry.start_time).to_formatted_s(:number)}\" />" if entry.start_time
34
+ time += "<end value=\"#{Time.at(entry.end_time).to_formatted_s(:number)}\" />" if entry.end_time
35
35
  time += "</effectiveTime>"
36
36
  else
37
37
  "<effectiveTime />"
@@ -61,7 +61,11 @@ module HealthDataStandards
61
61
 
62
62
  def quantity_display(value, tag_name="value")
63
63
  return unless value
64
- "<#{tag_name} value=\"#{value['value']}\" units=\"#{value['unit']}\" />"
64
+ if value.respond_to?(:scalar)
65
+ "<#{tag_name} value=\"#{value.scalar}\" units=\"#{value.units}\" />"
66
+ else
67
+ "<#{tag_name} value=\"#{value['value']}\" units=\"#{value['unit']}\" />"
68
+ end
65
69
  end
66
70
 
67
71
  def time_if_not_nil(*args)
@@ -79,6 +83,22 @@ module HealthDataStandards
79
83
  def is_bool?(str)
80
84
  return ["true","false"].include? (str || "").downcase
81
85
  end
86
+
87
+ def decode_qrda_section(section, oid)
88
+ if oid
89
+ HealthDataStandards::Util::QRDATemplateHelper.definition_for_template_id(oid)['definition'].pluralize.to_sym
90
+ else
91
+ section
92
+ end
93
+ end
94
+ def decode_qrda_status(status, oid)
95
+ if oid
96
+ HealthDataStandards::Util::QRDATemplateHelper.definition_for_template_id(oid)['status']
97
+ else
98
+ status
99
+ end
100
+ end
101
+
82
102
  end
83
103
  end
84
104
  end
@@ -29,8 +29,9 @@ module HealthDataStandards
29
29
  extract_codes(entry_element, allergy)
30
30
  extract_dates(entry_element, allergy)
31
31
  extract_description(entry_element, allergy, id_map)
32
+ extract_negation(entry_element, allergy)
32
33
 
33
- allergy.status = extract_status(entry_element, allergy)
34
+ extract_status(entry_element, allergy)
34
35
  allergy.type = extract_code(entry_element, @type_xpath)
35
36
  allergy.reaction = extract_code(entry_element, @reaction_xpath)
36
37
  allergy.severity = extract_code(entry_element, @severity_xpath)
@@ -22,7 +22,8 @@ module HealthDataStandards
22
22
  end
23
23
 
24
24
  entry = importer.create_entry(goal_element, id_map={})
25
-
25
+ extract_negation(goal_element, entry)
26
+
26
27
 
27
28
 
28
29
  if @check_for_usable
@@ -7,10 +7,11 @@ module HealthDataStandards
7
7
  @entry_xpath = "//cda:section[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.103']/cda:entry/cda:act/cda:entryRelationship/cda:observation"
8
8
  @code_xpath = "./cda:value"
9
9
  @status_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.1.50']/cda:value"
10
- @priority_xpath = "./cda:priorityCode"
10
+ @ordinality_xpath = "./cda:priorityCode"
11
11
  @description_xpath = "./cda:text/cda:reference[@value]"
12
12
  @provider_xpath = "./cda:act[cda:templateId/@root='2.16.840.1.113883.10.20.1.27']/cda:performer"
13
13
  @cod_xpath = "./cda:entryRelationship[@typeCode='CAUS']/cda:observation/cda:code[@code='419620001']"
14
+ @priority_xpath = "../cda:sequenceNumber"
14
15
  end
15
16
 
16
17
  def create_entries(doc, id_map = {})
@@ -24,10 +25,12 @@ module HealthDataStandards
24
25
  extract_codes(entry_element, condition)
25
26
  extract_dates(entry_element, condition)
26
27
  extract_status(entry_element, condition)
27
- extract_priority(entry_element, condition)
28
+ extract_ordinality(entry_element, condition)
28
29
  extract_description(entry_element, condition, id_map)
29
30
  extract_cause_of_death(entry_element, condition) if @cod_xpath
30
31
  extract_type(entry_element, condition)
32
+ extract_negation(entry_element, condition)
33
+ extract_priority(entry_element, condition)
31
34
 
32
35
  if @provider_xpath
33
36
  entry_element.xpath(@provider_xpath).each do |provider_element|
@@ -43,10 +46,28 @@ module HealthDataStandards
43
46
 
44
47
  private
45
48
 
49
+ def extract_ordinality(parent_element, entry)
50
+ ordinality_element = parent_element.at_xpath(@ordinality_xpath)
51
+ if ordinality_element
52
+ entry.ordinality_code = {CodeSystemHelper.code_system_for(ordinality_element['codeSystem']) => [ordinality_element['code']]}
53
+ case ordinality_element['code']
54
+ when '8319008'
55
+ entry.ordinality = :principal
56
+ end
57
+ end
58
+ end
59
+
46
60
  def extract_cause_of_death(entry_element, condition)
47
61
  cod = entry_element.at_xpath(@cod_xpath)
48
62
  condition.cause_of_death = cod.present?
49
63
  end
64
+
65
+ def extract_priority(entry_element, condition)
66
+ priority_element = entry_element.at_xpath(@priority_xpath)
67
+ if priority_element
68
+ condition.priority = priority_element['value'].to_i
69
+ end
70
+ end
50
71
 
51
72
  def extract_type(entry_element, condition)
52
73
  code_element = entry_element.at_xpath('./cda:code')
@@ -7,7 +7,6 @@ module HealthDataStandards
7
7
  def initialize
8
8
  @entry_xpath = "//cda:section[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.127']/cda:entry/cda:encounter"
9
9
  @code_xpath = "./cda:code"
10
- @status_xpath = "./cda:statusCode"
11
10
  @description_xpath = "./cda:code/cda:originalText/cda:reference[@value] | ./cda:text/cda:reference[@value]"
12
11
  @reason_xpath = "./cda:entryRelationship[@typeCode='RSON']/cda:act"
13
12
  @check_for_usable = true # Pilot tools will set this to false
@@ -42,6 +41,7 @@ module HealthDataStandards
42
41
  extract_performer(entry_element, encounter)
43
42
  extract_facility(entry_element, encounter)
44
43
  extract_reason(entry_element, encounter, id_map)
44
+ extract_negation(entry_element, encounter)
45
45
  extract_admission(entry_element, encounter)
46
46
  encounter
47
47
  end
@@ -56,10 +56,11 @@ module HealthDataStandards
56
56
  def extract_facility(parent_element, encounter)
57
57
  participant_element = parent_element.at_xpath("./cda:participant[@typeCode='LOC']/cda:participantRole[@classCode='SDLOC']")
58
58
  if (participant_element)
59
- org = Organization.new(name: participant_element.at_xpath("./cda:playingEntity/cda:name").try(:text))
60
- org.addresses = participant_element.xpath("./cda:addr").try(:map) {|ae| import_address(ae)}
61
- org.telecoms = participant_element.xpath("./cda:telecom").try(:map) {|te| import_telecom(te)}
62
- encounter.facility = org
59
+ facility = Facility.new(name: participant_element.at_xpath("./cda:playingEntity/cda:name").try(:text))
60
+ facility.addresses = participant_element.xpath("./cda:addr").try(:map) {|ae| import_address(ae)}
61
+ facility.telecoms = participant_element.xpath("./cda:telecom").try(:map) {|te| import_telecom(te)}
62
+ facility.code = extract_code(participant_element, './cda:code')
63
+ encounter.facility = facility
63
64
  end
64
65
  end
65
66
 
@@ -7,7 +7,6 @@ module HealthDataStandards
7
7
  @entry_xpath = "//cda:section[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.117']/cda:entry/cda:substanceAdministration"
8
8
  @code_xpath = "./cda:consumable/cda:manufacturedProduct/cda:manufacturedMaterial/cda:code"
9
9
  @description_xpath = "./cda:consumable/cda:manufacturedProduct/cda:manufacturedMaterial/cda:code/cda:originalText/cda:reference[@value]"
10
- @refusal_reason_xpath = "./cda:entryRelationship[@typeCode='RSON']/cda:act[cda:templateId/@root='2.16.840.1.113883.10.20.1.27']/cda:code"
11
10
  @check_for_usable = true # Pilot tools will set this to false
12
11
  end
13
12
 
@@ -25,7 +24,7 @@ module HealthDataStandards
25
24
  extract_codes(entry_element, immunization)
26
25
  extract_dates(entry_element, immunization)
27
26
  extract_description(entry_element, immunization, id_map)
28
- extract_refusal(entry_element, immunization)
27
+ extract_negation(entry_element, immunization)
29
28
  extract_performer(entry_element, immunization)
30
29
  if @check_for_usable
31
30
  immunization_list << immunization if immunization.usable?
@@ -37,19 +36,6 @@ module HealthDataStandards
37
36
  end
38
37
 
39
38
  private
40
- def extract_refusal(parent_element, immunization)
41
- negation_indicator = parent_element['negationInd']
42
- unless negation_indicator.nil?
43
- immunization.refusal_ind = negation_indicator.eql?('true')
44
- if immunization.refusal_ind
45
- refusal_reason_element = parent_element.at_xpath(@refusal_reason_xpath)
46
- if refusal_reason_element
47
- immunization.refusal_reason = {'code' => refusal_reason_element['code'],
48
- 'codeSystem' => 'HL7 No Immunization Reason'}
49
- end
50
- end
51
- end
52
- end
53
39
 
54
40
  def extract_performer(parent_element, immunization)
55
41
  performer_element = parent_element.at_xpath("./cda:performer")
@@ -50,6 +50,7 @@ module HealthDataStandards
50
50
  extract_order_information(entry_element, medication)
51
51
 
52
52
  extract_fulfillment_history(entry_element, medication)
53
+ extract_negation(entry_element, medication)
53
54
 
54
55
  medication
55
56
  end
@@ -97,9 +97,22 @@ module HealthDataStandards
97
97
  c32_patient = Record.new
98
98
  get_demographics(c32_patient, doc)
99
99
  create_c32_hash(c32_patient, doc)
100
+ check_for_cause_of_death(c32_patient)
100
101
 
101
102
  c32_patient
102
103
  end
104
+
105
+ # Checks the conditions to see if any of them have a cause of death set. If they do,
106
+ # it will set the expired field on the Record. This is done here rather than replacing
107
+ # the expried method on Record because other formats may actully tell you whether
108
+ # a patient is dead or not.
109
+ # @param [Record] c32_patient to check the conditions on and set the expired
110
+ # property if applicable
111
+ def check_for_cause_of_death(c32_patient)
112
+ if c32_patient.conditions.any? {|condition| condition.cause_of_death }
113
+ c32_patient.expired = true
114
+ end
115
+ end
103
116
 
104
117
  # Create a simple representation of the patient from a HITSP C32
105
118
  # @param [Record] record Mongoid model to append the Entry objects to
@@ -41,6 +41,7 @@ module HealthDataStandards
41
41
  extract_description(entry_element, procedure, id_map)
42
42
  extract_performer(entry_element, procedure)
43
43
  extract_site(entry_element, procedure)
44
+ extract_negation(entry_element, procedure)
44
45
  procedure
45
46
  end
46
47
 
@@ -54,7 +54,7 @@ module HealthDataStandards
54
54
  end
55
55
 
56
56
  def find_or_create_provider(provider_hash)
57
- provider = Provider.first(conditions: {npi: provider_hash[:npi]}) if provider_hash[:npi]
57
+ provider = Provider.where(npi: provider_hash[:npi]).first if provider_hash[:npi]
58
58
  provider ||= Provider.create(provider_hash)
59
59
  end
60
60
 
@@ -36,6 +36,7 @@ module HealthDataStandards
36
36
  extract_value(entry_element, result)
37
37
  extract_description(entry_element, result, id_map)
38
38
  extract_interpretation(entry_element, result)
39
+ extract_negation(entry_element, result)
39
40
  result
40
41
  end
41
42
 
@@ -67,9 +67,6 @@ module HealthDataStandards
67
67
  if @status_xpath
68
68
  extract_status(entry_element, entry)
69
69
  end
70
- if @priority_xpath
71
- extract_priority(entry_element, entry)
72
- end
73
70
  if @description_xpath
74
71
  extract_description(entry_element, entry, id_map)
75
72
  end
@@ -81,28 +78,10 @@ module HealthDataStandards
81
78
  def extract_status(parent_element, entry)
82
79
  status_element = parent_element.at_xpath(@status_xpath)
83
80
  if status_element
84
- case status_element['code']
85
- when '55561003'
86
- entry.status = :active
87
- when '73425007'
88
- entry.status = :inactive
89
- when '413322009'
90
- entry.status = :resolved
91
- end
92
- end
93
- end
94
-
95
- def extract_priority(parent_element, entry)
96
- priority_element = parent_element.at_xpath(@priority_xpath)
97
- if priority_element
98
- case priority_element['code']
99
- when '8319008'
100
- entry.ordinality = :principal
101
- end
81
+ entry.status_code = {CodeSystemHelper.code_system_for(status_element['codeSystem']) => [status_element['code']]}
102
82
  end
103
83
  end
104
84
 
105
-
106
85
  def extract_description(parent_element, entry, id_map)
107
86
  code_elements = parent_element.xpath(@description_xpath)
108
87
  code_elements.each do |code_element|
@@ -195,6 +174,22 @@ module HealthDataStandards
195
174
  tele
196
175
  end
197
176
 
177
+ def extract_negation(parent_element, entry)
178
+ negation_indicator = parent_element['negationInd']
179
+ unless negation_indicator.nil?
180
+ entry.negation_ind = negation_indicator.eql?('true')
181
+ if entry.negation_ind
182
+ negation_reason_element = parent_element.at_xpath("./cda:entryRelationship[@typeCode='RSON']/cda:act[cda:templateId/@root='2.16.840.1.113883.10.20.1.27']/cda:code")
183
+ if negation_reason_element
184
+ code_system_oid = negation_reason_element['codeSystem']
185
+ code = negation_reason_element['code']
186
+ code_system = HealthDataStandards::Util::CodeSystemHelper.code_system_for(code_system_oid)
187
+ entry.negation_reason = {'code' => code, 'codeSystem' => code_system}
188
+ end
189
+ end
190
+ end
191
+ end
192
+
198
193
  def extract_code(parent_element, code_xpath, code_system=nil)
199
194
  code_element = parent_element.at_xpath(code_xpath)
200
195
  code_hash = nil