health-data-standards 2.1.4 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -69,6 +69,7 @@ require_relative 'health-data-standards/models/metadata/change_info'
69
69
  require_relative 'health-data-standards/models/metadata/link_info'
70
70
  require_relative 'health-data-standards/models/metadata/pedigree'
71
71
 
72
+ require_relative 'health-data-standards/import/c32/locatable_import_utils'
72
73
  require_relative 'health-data-standards/import/c32/section_importer'
73
74
  require_relative 'health-data-standards/import/c32/allergy_importer'
74
75
  require_relative 'health-data-standards/import/c32/encounter_importer'
@@ -3,12 +3,15 @@ module HealthDataStandards
3
3
  module TemplateHelper
4
4
  attr_accessor :template_format
5
5
  attr_accessor :template_subdir
6
+ attr_accessor :template_directory
6
7
 
7
8
  def template_root
9
+ @template_directory ||= File.dirname(__FILE__)
10
+
8
11
  if @template_subdir
9
- return File.join(File.dirname(__FILE__), '..', '..', '..', 'templates', @template_subdir)
12
+ return File.join(@template_directory, '..', '..', '..', 'templates', @template_subdir)
10
13
  else
11
- return File.join(File.dirname(__FILE__), '..', '..', '..', 'templates')
14
+ return File.join(@template_directory, '..', '..', '..', 'templates')
12
15
  end
13
16
  end
14
17
 
@@ -33,6 +36,7 @@ module HealthDataStandards
33
36
  rendering_context = RenderingContext.new(locals)
34
37
  rendering_context.template_format = self.template_format
35
38
  rendering_context.template_subdir = self.template_subdir
39
+ rendering_context.template_directory = self.template_directory
36
40
  eruby = Erubis::EscapedEruby.new(erb)
37
41
  eruby.result(rendering_context.my_binding)
38
42
  end
@@ -99,6 +99,51 @@ module HealthDataStandards
99
99
  end
100
100
  end
101
101
 
102
+ def convert_field_to_hash(field, codes)
103
+ if (codes.is_a? Hash)
104
+ clean_hash = {}
105
+
106
+ if codes['codeSystem']
107
+ if codes['title']
108
+ clean_hash[codes['codeSystem']] = codes['code'] + " (#{codes['title']})"
109
+ else
110
+ clean_hash[codes['codeSystem']] = codes['code']
111
+ end
112
+ elsif codes['_id']
113
+ codes.keys.reject {|key| ['_id'].include? key}.each do |hashkey|
114
+ value = codes[hashkey]
115
+ if value.nil?
116
+ clean_hash[hashkey.titleize] = 'none'
117
+ elsif value.is_a? Hash
118
+ hash_result = convert_field_to_hash(hashkey, value)
119
+ if hash_result.is_a? Hash
120
+ clean_hash[hashkey.titleize] = hash_result.map {|key, value| "#{key}: #{value}"}.join(' ')
121
+ else
122
+ clean_hash[hashkey.titleize] = hash_result
123
+ end
124
+ elsif value.is_a? Array
125
+ clean_hash[hashkey.titleize] = value.join(', ')
126
+ else
127
+ clean_hash[hashkey.titleize] = convert_field_to_hash(hashkey, value)
128
+ end
129
+ end
130
+ elsif codes['scalar']
131
+ return "#{codes['scalar']} #{codes['units']}"
132
+ else
133
+ return codes.map {|hashcode_set, hashcodes| "#{hashcode_set}: #{(hashcodes.respond_to? :join) ? hashcodes.join(', ') : hashcodes.to_s}"}.join(' ')
134
+ end
135
+
136
+ clean_hash
137
+ else
138
+ if codes && (field.match(/Time$/) || field.match(/\_time$/))
139
+ Entry.time_to_s(codes)
140
+ else
141
+ codes.to_s
142
+ end
143
+ end
144
+ end
145
+
146
+
102
147
  end
103
148
  end
104
149
  end
@@ -49,11 +49,7 @@ module HealthDataStandards
49
49
  def extract_ordinality(parent_element, entry)
50
50
  ordinality_element = parent_element.at_xpath(@ordinality_xpath)
51
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
52
+ entry.ordinality = {CodeSystemHelper.code_system_for(ordinality_element['codeSystem']) => [ordinality_element['code']]}
57
53
  end
58
54
  end
59
55
 
@@ -0,0 +1,27 @@
1
+ module HealthDataStandards
2
+ module Import
3
+ module C32
4
+ # Helpers for importing C32 addresses and telecoms
5
+ module LocatableImportUtils
6
+ def import_address(address_element)
7
+ address = Address.new
8
+ address.use = address_element['use']
9
+ address.street = address_element.xpath("./cda:streetAddressLine").map {|street| street.text}
10
+ address.city = address_element.at_xpath("./cda:city").try(:text)
11
+ address.state = address_element.at_xpath("./cda:state").try(:text)
12
+ address.zip = address_element.at_xpath("./cda:postalCode").try(:text)
13
+ address.country = address_element.at_xpath("./cda:country").try(:text)
14
+ address
15
+ end
16
+
17
+ def import_telecom(telecom_element)
18
+ tele = Telecom.new
19
+ tele.value = telecom_element['value']
20
+ tele.use = telecom_element['use']
21
+ tele
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -11,6 +11,7 @@ module HealthDataStandards
11
11
 
12
12
  include Singleton
13
13
  include HealthDataStandards::Util
14
+ include HealthDataStandards::Import::C32::LocatableImportUtils
14
15
 
15
16
  # Creates a new PatientImporter with the following XPath expressions used to find content in
16
17
  # a HITSP C32:
@@ -150,10 +151,16 @@ module HealthDataStandards
150
151
  patient.race = { code: race_node['code'], code_set: 'CDC-RE' } if race_node
151
152
  ethnicity_node = patient_element.at_xpath('cda:ethnicGroupCode')
152
153
  patient.ethnicity = {code: ethnicity_node['code'], code_set: 'CDC-RE'} if ethnicity_node
153
-
154
154
  languages = patient_element.search('languageCommunication').map {|lc| lc.at_xpath('cda:languageCode')['code'] }
155
155
  patient.languages = languages unless languages.empty?
156
156
 
157
+ # parse address information
158
+ patient.addresses = doc.xpath('/cda:ClinicalDocument/cda:recordTarget/cda:patientRole/cda:addr').map do |addr_element|
159
+ import_address(addr_element)
160
+ end
161
+ patient.telecoms = doc.xpath('/cda:ClinicalDocument/cda:recordTarget/cda:patientRole/cda:telecom').map do |tele|
162
+ import_telecom(tele)
163
+ end
157
164
  end
158
165
  end
159
166
  end
@@ -4,6 +4,7 @@ module HealthDataStandards
4
4
  # Class that can be used to create an importer for a section of a HITSP C32 document. It usually
5
5
  # operates by selecting all CDA entries in a section and then creates entries for them.
6
6
  class SectionImporter
7
+ include HealthDataStandards::Import::C32::LocatableImportUtils
7
8
  include HealthDataStandards::Util
8
9
 
9
10
  attr_accessor :check_for_usable
@@ -157,23 +158,6 @@ module HealthDataStandards
157
158
  return person
158
159
  end
159
160
 
160
- def import_address(address_element)
161
- address = Address.new
162
- address.street = [address_element.at_xpath("./cda:streetAddressLine").try(:text)]
163
- address.city = address_element.at_xpath("./cda:city").try(:text)
164
- address.state = address_element.at_xpath("./cda:state").try(:text)
165
- address.zip = address_element.at_xpath("./cda:postalCode").try(:text)
166
- address.country = address_element.at_xpath("./cda:country").try(:text)
167
- address
168
- end
169
-
170
- def import_telecom(telecom_element)
171
- tele = Telecom.new
172
- tele.value = telecom_element['value']
173
- tele.use = telecom_element['use']
174
- tele
175
- end
176
-
177
161
  def extract_negation(parent_element, entry)
178
162
  negation_indicator = parent_element['negationInd']
179
163
  unless negation_indicator.nil?
@@ -6,6 +6,7 @@ class Address
6
6
  field :state, type: String
7
7
  field :zip, type: String
8
8
  field :country, type: String
9
+ field :use, type: String
9
10
 
10
11
  embedded_in :locatable, polymorphic: true
11
12
  end
@@ -3,8 +3,7 @@ class Condition < Entry
3
3
  field :causeOfDeath, type: Boolean
4
4
  field :priority, type: Integer
5
5
  field :name, type: String
6
- field :ordinality, type: String
7
- field :ordinality_code, type: Hash
6
+ field :ordinality, type: Hash
8
7
  field :severity, type: Hash # Currently unsupported by any importers
9
8
 
10
9
  embeds_many :treating_provider, class_name: "Provider"
@@ -1,18 +1,26 @@
1
1
  class Encounter < Entry
2
-
3
2
  field :admitType, type: Hash
4
3
  field :dischargeDisposition, type: Hash
5
- field :admit_time, type: Integer
6
- field :discharge_time, type: Integer
4
+ field :admitTime, type: Integer
5
+ field :dischargeTime, type: Integer
6
+ field :transferTo, type: Hash
7
+ field :transferFrom, type: Hash
7
8
 
8
9
  embeds_one :facility
9
10
  embeds_one :reason, class_name: "Entry"
10
11
 
11
12
  belongs_to :performer, class_name: "Provider"
12
13
 
14
+ alias :admit_time :admitTime
15
+ alias :admit_time= :admitTime=
13
16
  alias :admit_type :admitType
14
17
  alias :admit_type= :admitType=
15
18
  alias :discharge_disposition :dischargeDisposition
16
19
  alias :discharge_disposition= :dischargeDisposition=
17
-
20
+ alias :discharge_time :dischargeTime
21
+ alias :discharge_time= :dischargeTime=
22
+ alias :transfer_to :transferTo
23
+ alias :transfer_to= :transferTo=
24
+ alias :transfer_from :transferFrom
25
+ alias :transfer_from= :transferFrom=
18
26
  end
@@ -20,6 +20,7 @@ class Entry
20
20
  field :negationInd, type: Boolean
21
21
  field :negationReason, type: Hash
22
22
  field :oid, type: String
23
+ field :reason, type: Hash
23
24
 
24
25
  alias :negation_ind :negationInd
25
26
  alias :negation_ind= :negationInd=
@@ -33,14 +34,18 @@ class Entry
33
34
 
34
35
  def times_to_s(nil_string='UNK')
35
36
  if start_time.present? || end_time.present?
36
- start_string = start_time ? Time.at(start_time).utc.to_formatted_s(:long_ordinal) : nil_string
37
- end_string = end_time ? Time.at(end_time).utc.to_formatted_s(:long_ordinal) : nil_string
37
+ start_string = start_time ? Entry.time_to_s(start_time) : nil_string
38
+ end_string = end_time ? Entry.time_to_s(end_time) : nil_string
38
39
  "#{start_string} - #{end_string}"
39
40
  elsif time.present?
40
41
  Time.at(time).utc.to_formatted_s(:long_ordinal)
41
42
  end
42
43
  end
43
44
 
45
+ def self.time_to_s(input_time)
46
+ Time.at(input_time).utc.to_formatted_s(:long_ordinal)
47
+ end
48
+
44
49
  # Entry previously had a status field that dropped the code set and converted
45
50
  # the status to a String. Entry now preserves the original code and code set.
46
51
  # This method is here to maintain backwards compatibility.
@@ -69,8 +74,8 @@ class Entry
69
74
  self.status_code = {'SNOMED-CT' => ['73425007']}
70
75
  when 'resolved'
71
76
  self.status_code = {'SNOMED-CT' => ['413322009']}
72
- when 'completed'
73
- self.status_code = {'HL7 ActStatus' => ['completed']}
77
+ else
78
+ self.status_code = {'HL7 ActStatus' => [status_text]}
74
79
  end
75
80
  end
76
81
 
@@ -105,6 +110,8 @@ class Entry
105
110
 
106
111
  # Checks if a code is in the list of possible codes
107
112
  # @param [Array] code_set an Array of Hashes that describe the values for code sets
113
+ # The hash has a key of "set" for the code system name and "values"
114
+ # for the actual code list
108
115
  # @return [true, false] whether the code is in the list of desired codes
109
116
  def is_in_code_set?(code_set)
110
117
  codes.keys.each do |code_system|
@@ -2,7 +2,10 @@ class MedicalEquipment < Entry
2
2
 
3
3
  field :manufacturer, type: String
4
4
  field :anatomicalStructure, type: Hash
5
+ field :removalTime, type: Integer
5
6
 
6
7
  alias :anatomical_structure :anatomicalStructure
7
8
  alias :anatomical_structure= :anatomicalStructure=
9
+ alias :removal_time :removalTime
10
+ alias :removal_time= :removalTime=
8
11
  end
@@ -1,11 +1,11 @@
1
1
  class Procedure < Entry
2
- field :site, type: Hash
3
- field :incisionDateTime, type: Integer
4
- field :ordinality, type: String
5
- field :ordinality_code, type: Hash
2
+ field :site, type: Hash
3
+ field :incisionTime, type: Integer
4
+ field :ordinality, type: Hash
5
+ field :source, type: Hash
6
6
 
7
7
  belongs_to :performer, class_name: "Provider"
8
8
 
9
- alias :incision_date_time :incisionDateTime
10
- alias :incision_date_time= :incisionDateTime=
9
+ alias :incision_time :incisionTime
10
+ alias :incision_time= :incisionTime=
11
11
  end
@@ -41,6 +41,8 @@ class Record
41
41
  :insurance_providers, :functional_statuses]
42
42
 
43
43
  embeds_many :provider_performances
44
+ embeds_many :addresses, as: :locatable
45
+ embeds_many :telecoms, as: :contactable
44
46
 
45
47
  scope :by_provider, ->(prov, effective_date) { (effective_date) ? where(provider_queries(prov.id, effective_date)) : where('provider_performances.provider_id'=>prov.id) }
46
48
  scope :by_patient_id, ->(id) { where(:medical_record_number => id) }
@@ -57,7 +59,7 @@ class Record
57
59
  matching_entries_by_section = Sections.map do |section|
58
60
  section_entries = self.send(section)
59
61
  if section_entries.present?
60
- section_entries.find_all { |entry| entry.oid == oid }
62
+ section_entries.find_all { |entry| (entry.respond_to? :oid) ? entry.oid == oid : false}
61
63
  else
62
64
  []
63
65
  end
@@ -2,28 +2,72 @@ module HealthDataStandards
2
2
  module SVS
3
3
  class ValueSet
4
4
 
5
- include Mongoid::Document
5
+ include Mongoid::Document
6
6
  field :oid, type: String
7
7
  field :display_name, type: String
8
8
  field :version, type: String
9
9
 
10
+ index({oid: 1})
11
+ index({display_name: 1})
10
12
  embeds_many :concepts
13
+ index "concepts.code" => 1
14
+ index "concepts.code_system" => 1
15
+ index "concepts.code_system_name" => 1
16
+ index "concepts.display_name" => 1
17
+
11
18
  scope :by_oid, ->(oid){where(:oid => oid)}
12
19
 
20
+ # Provides an Array of Hashes. Each code system gets its own Hash
21
+ # The hash has a key of "set" for the code system name and "values"
22
+ # for the actual code list
23
+ def code_set_map
24
+ codes = []
25
+ self.concepts.inject({}) do |memo, concept|
26
+ memo[concept.code_system_name] ||= []
27
+ memo[concept.code_system_name] << concept.code
28
+ memo
29
+ end.each_pair do |code_set, code_list|
30
+ codes << {"set" => code_set, "values" => code_list}
31
+ end
32
+
33
+ codes
34
+ end
35
+
13
36
  def self.load_from_xml(doc)
14
- doc.root.add_namespace_definition("vs","urn:ihe:iti:svs:2008")
15
- vs_element = doc.at_xpath("/vs:RetrieveValueSetResponse/vs:ValueSet")
16
- if vs_element
17
- vs = ValueSet.new(oid: vs_element["ID"], display_name: vs_element["displayName"], version: vs_element["version"])
18
- concepts = vs_element.xpath("//vs:Concept").collect do |con|
19
- Concept.new(code: con["code"],
20
- code_system_name: con["codeSystemName"],
21
- code_system_version: con["code_system_version"],
22
- display_name: con["displayName"],code_system: con["codeSystem"])
23
- end
24
- vs.concepts = concepts
25
- return vs
26
- end
37
+ doc.root.add_namespace_definition("vs","urn:ihe:iti:svs:2008")
38
+ vs_element = doc.at_xpath("/vs:RetrieveValueSetResponse/vs:ValueSet")
39
+ if vs_element
40
+ vs = ValueSet.new(oid: vs_element["ID"], display_name: vs_element["displayName"], version: vs_element["version"])
41
+ concepts = vs_element.xpath("//vs:Concept").collect do |con|
42
+ Concept.new(code: con["code"],
43
+ code_system_name: normalize_code_set_name(con["codeSystemName"]),
44
+ code_system_version: con["code_system_version"],
45
+ display_name: con["displayName"], code_system: con["codeSystem"])
46
+ end
47
+ vs.concepts = concepts
48
+ return vs
49
+ end
50
+ end
51
+
52
+ def self.normalize_code_set_name(code_set_name)
53
+ case code_set_name
54
+ when 'RXNORM'
55
+ 'RxNorm'
56
+ when 'ICD9CM'
57
+ 'ICD-9-CM'
58
+ when 'ICD10CM'
59
+ 'ICD-10-CM'
60
+ when 'ICD10PCS'
61
+ 'ICD-10-PCS'
62
+ when 'SNOMEDCT'
63
+ 'SNOMED-CT'
64
+ when 'CDCREC'
65
+ 'CDC Race'
66
+ when 'HSLOC'
67
+ 'HL7 Healthcare Service Location'
68
+ else
69
+ code_set_name
70
+ end
27
71
  end
28
72
  end
29
73
  end
@@ -14,7 +14,7 @@ module ThingWithCodes
14
14
  def self.convert_codes_to_s(codes)
15
15
  codes.map {|code_set, codes| "#{code_set}: #{codes.join(', ')}"}.join(' ')
16
16
  end
17
-
17
+
18
18
  # Will return a single code and code set if one exists in the code sets that are
19
19
  # passed in. Returns a hash with a key of code and code_set if found, nil otherwise
20
20
  def preferred_code(preferred_code_sets, codes_attribute=:codes)
@@ -9,7 +9,8 @@ module HealthDataStandards
9
9
  #'2.16.840.1.113883.3.88.12.80.32' => 'CPT', # Encounter Type from C32, a subset of CPT
10
10
  '2.16.840.1.113883.6.88' => 'RxNorm',
11
11
  '2.16.840.1.113883.6.103' => 'ICD-9-CM',
12
- '2.16.840.1.113883.6.104' => 'ICD-9-CM',
12
+ '2.16.840.1.113883.6.104' => 'ICD-9-PCS',
13
+ '2.16.840.1.113883.6.4' => 'ICD-10-PCS',
13
14
  '2.16.840.1.113883.6.90' => 'ICD-10-CM',
14
15
  '2.16.840.1.113883.6.14' => 'HCPCS',
15
16
  '2.16.840.1.113883.6.59' => 'CVX',
@@ -18,9 +19,16 @@ module HealthDataStandards
18
19
  '2.16.840.1.113883.3.88.12.80.20' => 'FDA',
19
20
  '2.16.840.1.113883.5.14' => 'HL7 ActStatus',
20
21
  '2.16.840.1.113883.6.259' => 'HL7 Healthcare Service Location',
22
+ '2.16.840.1.113883.12.112' => 'DischargeDisposition',
21
23
  '2.16.840.1.113883.5.4' => 'HL7 Act Code',
22
24
  '2.16.840.1.113883.1.11.18877' => 'HL7 Relationship Code',
23
- '2.16.840.1.113883.6.238' => 'CDC Race'
25
+ '2.16.840.1.113883.6.238' => 'CDC Race',
26
+ '2.16.840.1.113883.6.177' => 'NLM MeSH'
27
+ }
28
+
29
+ CODE_SYSTEM_ALIASES = {
30
+ 'FDA SPL' => 'NCI Thesaurus',
31
+ 'HSLOC' => 'HL7 Healthcare Service Location'
24
32
  }
25
33
 
26
34
  # Returns the name of a code system given an oid
@@ -34,6 +42,7 @@ module HealthDataStandards
34
42
  # @param [String] the name of the code system
35
43
  # @return [String] the oid of the code system
36
44
  def self.oid_for_code_system(code_system)
45
+ code_system = CODE_SYSTEM_ALIASES[code_system] if CODE_SYSTEM_ALIASES[code_system]
37
46
  CODE_SYSTEMS.invert[code_system]
38
47
  end
39
48
 
@@ -140,8 +140,8 @@
140
140
  "status":"resolved",
141
141
  "negation":false},
142
142
  "2.16.840.1.113883.3.560.1.32":{
143
- "definition":"diagnosis_family_history",
144
- "status":"",
143
+ "definition":"diagnosis",
144
+ "status":"family_history",
145
145
  "negation":false},
146
146
  "2.16.840.1.113883.3.560.1.23":{
147
147
  "definition":"diagnosis",
@@ -156,8 +156,8 @@
156
156
  "status":"resolved",
157
157
  "negation":true},
158
158
  "2.16.840.1.113883.3.560.1.132":{
159
- "definition":"diagnosis_family_history",
160
- "status":"",
159
+ "definition":"diagnosis",
160
+ "status":"family_history",
161
161
  "negation":true},
162
162
  "2.16.840.1.113883.3.560.1.123":{
163
163
  "definition":"diagnosis",
@@ -220,8 +220,8 @@
220
220
  "status":"ordered",
221
221
  "negation":false},
222
222
  "2.16.840.1.113883.3.560.1.199":{
223
- "definition":"medication_discharge",
224
- "status":"",
223
+ "definition":"medication",
224
+ "status":"discharge",
225
225
  "negation":false},
226
226
  "2.16.840.1.113883.3.560.1.13":{
227
227
  "definition":"medication",
@@ -275,10 +275,6 @@
275
275
  "definition":"medication",
276
276
  "status":"administered",
277
277
  "negation":true},
278
- "2.16.840.1.113883.3.560.1.19":{
279
- "definition":"physical_exam",
280
- "status":"",
281
- "negation":false},
282
278
  "2.16.840.1.113883.3.560.1.18":{
283
279
  "definition":"physical_exam",
284
280
  "status":"",
@@ -2,12 +2,12 @@
2
2
  if preferred_code
3
3
  code_system_oid = HealthDataStandards::Util::CodeSystemHelper.oid_for_code_system(preferred_code['code_set'])
4
4
  -%>
5
- <code code="<%= preferred_code['code'] %>" codeSystem="<%= code_system_oid %>" displayName="<%= entry.description %>">
5
+ <code code="<%= preferred_code['code'] %>" codeSystem="<%= code_system_oid %>" codeSystemName="<%= preferred_code['code_set'] %>" displayName="<%= entry.description %>">
6
6
  <% else -%>
7
7
  <code nullFlavor="UNK">
8
8
  <% end -%>
9
9
  <originalText><reference value="#<%= section %>-desc-<%= i %>"/></originalText>
10
10
  <% entry.translation_codes(preferred_code_sets).each do |translation| -%>
11
- <translation code="<%= translation['code'] %>" codeSystem="<%= HealthDataStandards::Util::CodeSystemHelper.oid_for_code_system(translation['code_set']) %>" />
11
+ <translation code="<%= translation['code'] %>" codeSystem="<%= HealthDataStandards::Util::CodeSystemHelper.oid_for_code_system(translation['code_set']) %>" codeSystemName="<%= translation['code_set'] %>"/>
12
12
  <% end -%>
13
13
  </code>
@@ -15,7 +15,7 @@
15
15
  <%
16
16
  matches = []
17
17
  codes.each do |code|
18
- matches.concat(concept_map[set][code].values)
18
+ matches.concat(concept_map[set][code].values) if concept_map[set][code]
19
19
  end
20
20
  %>
21
21
  <ul id="<%=entry.id%>_<%=set%>" style="display: none; position: absolute; background: #EEE; padding: 10px; padding-left: 30px; width: 600px; z-index: 3000;">
@@ -37,7 +37,7 @@
37
37
  <% value.codes.each do |system, vals| %>
38
38
  <%= system %>: <%= vals.join(',') %>
39
39
  <% end %>
40
- <%= (value.description ? "(#{value.description})" : "(UNKNOWN CODED VALUE)")%>
40
+ <%= (value.description ? "(#{value.description})" : '')%>
41
41
  <br/>
42
42
  <% else %>
43
43
  UNKNOWN VALUE
@@ -46,19 +46,22 @@
46
46
  </td>
47
47
  <td>
48
48
  <%
49
- (entry.attributes.keys.reject {|key| ['codes', 'time', 'description', 'mood_code', 'values', '_id', '_type', 'start_time', 'end_time', 'status_code', 'negationInd', 'negationReason', 'oid'].include? key}).each do |field|
50
- field_value = ThingWithCodes.convert_codes_to_s(entry.attributes[field]) rescue entry.attributes[field].to_s
49
+ (entry.attributes.keys.reject {|key| ['codes', 'time', 'description', 'mood_code', 'values', '_id', '_type', 'start_time', 'end_time', 'status_code', 'negationInd', 'oid'].include? key}).each do |field|
50
+ field_value = convert_field_to_hash(field, entry.attributes[field])
51
+
51
52
  %>
52
- <%= field %>: (<b><%= field_value %></b>)
53
- <%
54
- end
55
- if entry.negationInd
56
- negation_reason = ''
57
- if entry.negationReason
58
- negation_reason = ThingWithCodes.convert_codes_to_s(entry.negationReason) rescue entry.negationReason.to_s
59
- end
60
- %>
61
- negation: <%= negation_reason %>
53
+ <% if field_value && !field_value.empty? %>
54
+ <dl>
55
+ <% if field_value.is_a? Hash %>
56
+ <dt><b><%= field.titleize %>:</b></dt>
57
+ <% field_value.keys.each do |fieldkey| %>
58
+ <dd><%= fieldkey %>: <i><%= field_value[fieldkey] %></i></dd>
59
+ <% end %>
60
+ <% else %>
61
+ <dt><b><%= field.titleize %></b>: <%= field_value%></dt>
62
+ <% end %>
63
+ <dl>
64
+ <% end %>
62
65
  <%
63
66
  end
64
67
  %>
@@ -26,7 +26,29 @@
26
26
  </tr>
27
27
  <tr>
28
28
  <td bgcolor="#3399ff"><span class="td_label">Contact info</span></td>
29
- <td colspan="3"> Pirmary Home: 202 Burlington Rd. Bedford, MA 01730<br />Tel: +1-781-271-3000</td>
29
+ <td colspan="3">
30
+ <% if patient.addresses %>
31
+ <% patient.addresses.each do |addr| %>
32
+ <% addr.street.each do |street| %>
33
+ <%= "#{street}," %>
34
+ <% end %>
35
+ <%= "#{addr.city}, #{addr.state}, #{addr.zip}." %>
36
+ <% if addr.use %>
37
+ (<%= addr.use %>)
38
+ <% end %>
39
+ <br />
40
+ <% end %>
41
+ <% end %>
42
+ <% if patient.telecoms %>
43
+ <% patient.telecoms.each do |telecom| %>
44
+ <%= telecom.value %>
45
+ <% if telecom.use %>
46
+ (<%= telecom.use %>)
47
+ <% end %>
48
+ <br />
49
+ <% end %>
50
+ <% end %>
51
+ </td>
30
52
  </tr>
31
53
  </tbody>
32
54
  </table>
@@ -51,7 +73,7 @@
51
73
  <tr>
52
74
  <td bgcolor="#3399ff"><span class="td_label">Contact info</span></td>
53
75
  <td>
54
- <br />Tel: +1-781-271-3000<br />
76
+ Tel: +1-781-271-3000<br />
55
77
  </td>
56
78
  </tr>
57
79
  </tbody>
@@ -112,7 +112,6 @@
112
112
  <div>
113
113
  <h3><a href="#" onclick="toggle('table_by_encounter');" id="toggle_button">View By Encounter</a></h3>
114
114
  </div>
115
-
116
115
  <%== render :partial => 'entries_by_section', :locals => {patient: patient, concept_map: concept_map} %>
117
116
  <%== render :partial => 'entries_by_encounter', :locals => {patient: patient, concept_map: concept_map} %>
118
117
 
@@ -17,13 +17,20 @@
17
17
  <recordTarget>
18
18
  <patientRole>
19
19
  <id root="Cypress" extension="<%= patient.id %>"/>
20
- <addr use="HP">
21
- <streetAddressLine>202 Burlington Rd.</streetAddressLine>
22
- <city>Bedford</city>
23
- <state>MA</state>
24
- <postalCode>01730</postalCode>
20
+ <% patient.addresses.each do |address| %>
21
+ <addr <%= address.use ? "use='#{address.use}'" : "" %>>
22
+ <% address.street.each do |street| %>
23
+ <streetAddressLine><%= street %></streetAddressLine>
24
+ <% end %>
25
+ <city><%= address.city %></city>
26
+ <state><%= address.state %></state>
27
+ <postalCode><%= address.zip %></postalCode>
28
+ <country><%= address.country %></country>
25
29
  </addr>
26
- <telecom value="tel:+1-781-271-3000"/>
30
+ <% end %>
31
+ <% patient.telecoms.each do |telecom| %>
32
+ <telecom value='<%= telecom.value %>' <%= telecom.use ? "use='#{telecom.use}'" : "" %>/>
33
+ <% end %>
27
34
  <patient>
28
35
  <name>
29
36
  <given><%= patient.first %></given>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: health-data-standards
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.4
4
+ version: 2.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-11-15 00:00:00.000000000 Z
15
+ date: 2012-12-19 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -53,7 +53,7 @@ dependencies:
53
53
  requirements:
54
54
  - - ~>
55
55
  - !ruby/object:Gem::Version
56
- version: 3.0.6
56
+ version: 3.0.14
57
57
  type: :runtime
58
58
  prerelease: false
59
59
  version_requirements: !ruby/object:Gem::Requirement
@@ -61,7 +61,23 @@ dependencies:
61
61
  requirements:
62
62
  - - ~>
63
63
  - !ruby/object:Gem::Version
64
- version: 3.0.6
64
+ version: 3.0.14
65
+ - !ruby/object:Gem::Dependency
66
+ name: activesupport
67
+ requirement: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ~>
71
+ - !ruby/object:Gem::Version
72
+ version: 3.2.9
73
+ type: :runtime
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ~>
79
+ - !ruby/object:Gem::Version
80
+ version: 3.2.9
65
81
  - !ruby/object:Gem::Dependency
66
82
  name: uuid
67
83
  requirement: !ruby/object:Gem::Requirement
@@ -137,6 +153,7 @@ files:
137
153
  - lib/health-data-standards/import/c32/encounter_importer.rb
138
154
  - lib/health-data-standards/import/c32/immunization_importer.rb
139
155
  - lib/health-data-standards/import/c32/insurance_provider_importer.rb
156
+ - lib/health-data-standards/import/c32/locatable_import_utils.rb
140
157
  - lib/health-data-standards/import/c32/medical_equipment_importer.rb
141
158
  - lib/health-data-standards/import/c32/medication_importer.rb
142
159
  - lib/health-data-standards/import/c32/organization_importer.rb