health-data-standards 3.4.5 → 3.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -8
- data/lib/health-data-standards.rb +4 -3
- data/lib/health-data-standards/import/bulk_record_importer.rb +44 -35
- data/lib/health-data-standards/import/cat1/procedure_performed_importer.rb +2 -13
- data/lib/health-data-standards/models/cqm/measure.rb +77 -1
- data/lib/health-data-standards/models/cqm/prefilter.rb +34 -0
- data/lib/health-data-standards/models/insurance_provider.rb +0 -1
- data/lib/health-data-standards/models/record.rb +10 -9
- data/lib/health-data-standards/models/thing_with_codes.rb +8 -6
- data/templates/cat1/_record_target.cat1.erb +5 -8
- data/templates/cat3/_author.cat3.erb +1 -1
- data/templates/cat3/_continuous_variable_value.cat3.erb +2 -2
- data/templates/cat3/_measure_data.cat3.erb +12 -3
- data/templates/cat3/_organization.cat3.erb +0 -1
- data/templates/cat3/show.cat3.erb +1 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fac1ae0fcbbd6b03dfdfe42628158c70acdca202
|
4
|
+
data.tar.gz: 80d25a9fdca4418440341a210a1ecad16bd12260
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6ce76c141974dd7d0b97c1b2603ced0aa6fa51f2bb5a0371111e7f3fd64ebb2377a6e0097953a509786401337b311a245fbd012835982798536c70823f6b734
|
7
|
+
data.tar.gz: ae3f4f96b405d1f10c4efb3411a583f70da9b8ac83e69b0ecdeffa3f02b0331de8868291f029296f771d1d62141eb68374a4726e8d8d650ee7271edf9d7e378a
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
This is a project to generate and consume HITSP C32, ASTM CCR, QRDA Category I, QRDA Category III and PQRI.
|
2
2
|
|
3
|
-
In addition this project also contains
|
3
|
+
In addition this project also contains libraries for parsing HQMF documents and for dealing with NLM valuesets.
|
4
4
|
|
5
5
|
Environment
|
6
6
|
===========
|
@@ -25,9 +25,19 @@ Please try to follow the [GitHub Coding Style Guides](https://github.com/stylegu
|
|
25
25
|
Change Log
|
26
26
|
==========
|
27
27
|
|
28
|
-
3.4.
|
28
|
+
3.4.6 - May 15, 2014
|
29
29
|
|
30
|
-
*
|
30
|
+
* QRDA Cat I export now exports medical record number if present
|
31
|
+
* Measures can now generate prefilter queries to be passed to MongoDB before CQM MapReduce jobs
|
32
|
+
* BulkRecordImporter now handles JSON records and has better error handling
|
33
|
+
* Bug fix - QRDA Cat III export uses correct XML element name for representedCustodianOrganization
|
34
|
+
* Bug fix - QRDA Cat III export now properly represents CV measures
|
35
|
+
* Bug fix - QRDA Cat I import now properly stores procedure performed ordinality
|
36
|
+
* Bug fix - InsuranceProvider model included ThingsWithCodes twice
|
37
|
+
|
38
|
+
3.4.5 - April 4, 2014
|
39
|
+
|
40
|
+
* Performance improvements in all exports through template caching
|
31
41
|
* QRDA Cat I export now exports the record's actual address if present
|
32
42
|
* QRDA Cat I export - Bug fix - previously patients with a race but no ethnicity would cause exceptions
|
33
43
|
* QRDA Cat I import - performance improvements through more efficient XPath expressions
|
@@ -47,11 +57,11 @@ Change Log
|
|
47
57
|
3.4.2 - February 28, 2014
|
48
58
|
|
49
59
|
* Provider improvements
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
60
|
+
* Providers are now exported in QRDA Cat I if they exist on the Record object
|
61
|
+
* Provider identifiers are now represented with CDAIdentifiers
|
62
|
+
* Provider import will now import any type of identifier
|
63
|
+
* Providers can now be arranged in a hierarchy
|
64
|
+
* When importing providers from a clinical document, matching to existing providers in MongoDB has been improved to matching on any type of identifier
|
55
65
|
* QRDA Cat I importer now imports procedure values regardless of whether the template has them at the root level or nested in an entryRelationship
|
56
66
|
* Bug fix - Result importer will no longer double import result values
|
57
67
|
* QRDA Cat I importer now imports encounter order end times
|
@@ -53,7 +53,7 @@ require_relative 'health-data-standards/models/medication'
|
|
53
53
|
require_relative 'health-data-standards/models/procedure'
|
54
54
|
require_relative 'health-data-standards/models/lab_result'
|
55
55
|
require_relative 'health-data-standards/models/functional_status'
|
56
|
-
require_relative 'health-data-standards/models/medical_equipment'
|
56
|
+
require_relative 'health-data-standards/models/medical_equipment'
|
57
57
|
require_relative 'health-data-standards/models/record'
|
58
58
|
require_relative 'health-data-standards/models/personable'
|
59
59
|
require_relative 'health-data-standards/models/provider'
|
@@ -88,6 +88,7 @@ require_relative 'health-data-standards/models/qrda/header'
|
|
88
88
|
require_relative 'health-data-standards/models/cqm/aggregate_objects'
|
89
89
|
require_relative 'health-data-standards/models/cqm/query_cache'
|
90
90
|
require_relative 'health-data-standards/models/cqm/bundle'
|
91
|
+
require_relative 'health-data-standards/models/cqm/prefilter'
|
91
92
|
require_relative 'health-data-standards/models/cqm/measure'
|
92
93
|
require_relative 'health-data-standards/models/cqm/patient_cache'
|
93
94
|
|
@@ -149,7 +150,7 @@ require_relative 'health-data-standards/import/green_c32/encounter_importer'
|
|
149
150
|
require_relative 'health-data-standards/import/green_c32/medication_importer'
|
150
151
|
require_relative 'health-data-standards/import/green_c32/allergy_importer'
|
151
152
|
require_relative 'health-data-standards/import/green_c32/social_history_importer'
|
152
|
-
require_relative 'health-data-standards/import/green_c32/immunization_importer'
|
153
|
+
require_relative 'health-data-standards/import/green_c32/immunization_importer'
|
153
154
|
require_relative 'health-data-standards/import/green_c32/support_importer'
|
154
155
|
require_relative 'health-data-standards/import/green_c32/advance_directive_importer'
|
155
156
|
require_relative 'health-data-standards/import/green_c32/medical_equipment_importer'
|
@@ -186,7 +187,7 @@ module HealthDataStandards
|
|
186
187
|
end
|
187
188
|
|
188
189
|
if defined?(Rails)
|
189
|
-
require_relative 'health-data-standards/railtie'
|
190
|
+
require_relative 'health-data-standards/railtie'
|
190
191
|
else
|
191
192
|
HealthDataStandards.logger = Log4r::Logger.new("Health Data Standards")
|
192
193
|
HealthDataStandards.logger.outputters = Log4r::Outputter.stdout
|
@@ -3,48 +3,59 @@ module HealthDataStandards
|
|
3
3
|
module Import
|
4
4
|
class BulkRecordImporter
|
5
5
|
|
6
|
-
def self.import_directory(source_dir)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
6
|
+
def self.import_directory(source_dir, failed_dir=nil)
|
7
|
+
failed_dir ||= File.join(source_dir, '../', 'failed_imports')
|
8
|
+
files = Dir.glob(File.join(source_dir, '*.*'))
|
9
|
+
files.each do |file|
|
10
|
+
BulkRecordImporter.import_file(file,File.new(file).read,failed_dir)
|
28
11
|
end
|
29
12
|
end
|
30
13
|
|
31
|
-
def self.import_archive(file)
|
14
|
+
def self.import_archive(file, failed_dir=nil)
|
15
|
+
begin
|
16
|
+
failed_dir ||=File.join(File.dirname(file))
|
32
17
|
Zip::ZipFile.open(file.path) do |zipfile|
|
33
18
|
zipfile.entries.each do |entry|
|
34
19
|
next if entry.directory?
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
20
|
+
data = zipfile.read(entry.name)
|
21
|
+
BulkRecordImporter.import_file(entry.name,data,failed_dir)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
rescue
|
25
|
+
FileUtils.mkdir_p(failed_dir)
|
26
|
+
File.cp(file,File.join(failed_dir,file))
|
27
|
+
File.open(File.join(failed_dir,"#{file}.error")) do |f|
|
28
|
+
f.puts($!.message)
|
29
|
+
f.puts($!.backtrace)
|
30
|
+
end
|
31
|
+
raise $!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.import_file(name,data,failed_dir,provider_map={})
|
36
|
+
begin
|
37
|
+
ext = File.extname(name)
|
38
|
+
if ext == ".json"
|
39
|
+
BulkRecordImporter.import_json(data)
|
40
|
+
else
|
41
|
+
BulkRecordImporter.import(data)
|
42
|
+
end
|
43
|
+
rescue
|
44
|
+
FileUtils.mkdir_p(File.dirname(File.join(failed_dir,name)))
|
45
|
+
File.open(File.join(failed_dir,name),"w") do |f|
|
46
|
+
f.puts(data)
|
47
|
+
end
|
48
|
+
File.open(File.join(failed_dir,"#{name}.error"),"w") do |f|
|
49
|
+
f.puts($!.message)
|
50
|
+
f.puts($!.backtrace)
|
45
51
|
end
|
46
52
|
end
|
47
53
|
end
|
54
|
+
|
55
|
+
def self.import_json(data,provider_map = {})
|
56
|
+
json = JSON.parse(data,:max_nesting=>100)
|
57
|
+
Record.update_or_create(Record.new(json))
|
58
|
+
end
|
48
59
|
|
49
60
|
def self.import(xml_data, provider_map = {})
|
50
61
|
doc = Nokogiri::XML(xml_data)
|
@@ -84,8 +95,6 @@ module HealthDataStandards
|
|
84
95
|
end
|
85
96
|
end
|
86
97
|
record.save
|
87
|
-
|
88
|
-
{status: 'success', message: 'patient imported', status_code: 201, record: record}
|
89
98
|
|
90
99
|
end
|
91
100
|
end
|
@@ -1,31 +1,20 @@
|
|
1
1
|
module HealthDataStandards
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
|
-
class ProcedurePerformedImporter < CDA::
|
4
|
+
class ProcedurePerformedImporter < CDA::ProcedureImporter
|
5
5
|
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:procedure[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.64']"))
|
6
6
|
super(entry_finder)
|
7
|
-
@entry_class = Procedure
|
8
|
-
@ordinality_xpath = "./cda:priorityCode"
|
9
7
|
@incision_xpath ="./cda:entryRelationship/cda:procedure[./cda:templateId[@root='2.16.840.1.113883.10.20.24.3.89']]/cda:effectiveTime"
|
10
8
|
end
|
11
|
-
|
9
|
+
|
12
10
|
def create_entry(entry_element, nrh = CDA::NarrativeReferenceHandler.new)
|
13
11
|
procedure = super
|
14
|
-
extract_ordinality(entry_element, procedure)
|
15
12
|
extract_incision_date_time(entry_element,procedure)
|
16
|
-
extract_negation(entry_element, procedure)
|
17
13
|
procedure
|
18
14
|
end
|
19
15
|
|
20
16
|
private
|
21
17
|
|
22
|
-
def extract_ordinality(parent_element, procedure)
|
23
|
-
ordinality_element = parent_element.at_xpath(@ordinality_xpath)
|
24
|
-
if ordinality_element
|
25
|
-
procedure.ordinality = {CodeSystemHelper.code_system_for(ordinality_element['codeSystem']) => [ordinality_element['code']]}
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
18
|
def extract_incision_date_time(parent_element, procedure)
|
30
19
|
incision_time = parent_element.at_xpath(@incision_xpath)
|
31
20
|
if incision_time
|
@@ -29,6 +29,9 @@ module HealthDataStandards
|
|
29
29
|
field :populations, type: Array
|
30
30
|
field :preconditions, type: Hash
|
31
31
|
field :hqmf_document, type: Hash
|
32
|
+
|
33
|
+
embeds_many :prefilters
|
34
|
+
|
32
35
|
scope :top_level_by_type , ->(type){where({"type"=> type}).any_of({"sub_id" => nil}, {"sub_id" => "a"})}
|
33
36
|
scope :top_level , any_of({"sub_id" => nil}, {"sub_id" => "a"})
|
34
37
|
scope :order_by_id_sub_id, order_by([["id", :asc],["sub_id", :asc]])
|
@@ -135,6 +138,79 @@ module HealthDataStandards
|
|
135
138
|
end
|
136
139
|
@crit
|
137
140
|
end
|
141
|
+
|
142
|
+
# Builds the query hash to pass to MongoDB
|
143
|
+
# Calling this method will create Prefilters if they do not exist on the
|
144
|
+
# measure
|
145
|
+
def prefilter_query!(effective_time)
|
146
|
+
self.build_pre_filters! if self.prefilters.empty?
|
147
|
+
|
148
|
+
if self.prefilters.count == 1
|
149
|
+
self.prefilters.first.build_query_hash(effective_time)
|
150
|
+
else
|
151
|
+
self.prefilters.inject({}) do |query, pf|
|
152
|
+
query.merge(pf.build_query_hash(effective_time)) do |key, new_val, old_val|
|
153
|
+
new_val.merge(old_val)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# For submeasures, this will return something like IPP_1
|
160
|
+
def ipp_id
|
161
|
+
ipp_hqmf_id = self.population_ids['IPP']
|
162
|
+
pop_id, pop_criteria = hqmf_document['population_criteria'].find do |population_id, population_criteria|
|
163
|
+
population_criteria['hqmf_id'] == ipp_hqmf_id
|
164
|
+
end
|
165
|
+
pop_id
|
166
|
+
end
|
167
|
+
|
168
|
+
def build_pre_filters!
|
169
|
+
dc = self.data_criteria.inject({}) do |all_dc, single_dc|
|
170
|
+
key = single_dc.keys.first
|
171
|
+
value = single_dc.values.first
|
172
|
+
all_dc[key] = value
|
173
|
+
all_dc
|
174
|
+
end
|
175
|
+
dc.each_pair do |criteria_name, data_criteria|
|
176
|
+
if data_criteria['definition'] == 'patient_characteristic_birthdate'
|
177
|
+
if data_criteria_in_population?(self.ipp_id, criteria_name)
|
178
|
+
prefilter = Prefilter.new(record_field: 'birthdate',
|
179
|
+
effective_time_based: true)
|
180
|
+
if data_criteria['temporal_references']
|
181
|
+
data_criteria['temporal_references'].each do |tr|
|
182
|
+
if tr['type'] == 'SBS' && tr['reference'] == 'MeasurePeriod'
|
183
|
+
years = nil
|
184
|
+
if tr['range']['high']
|
185
|
+
prefilter.comparison = '$gte'
|
186
|
+
years = tr['range']['high']['value'].to_i
|
187
|
+
elsif tr['range']['low']
|
188
|
+
prefilter.comparison = '$lte'
|
189
|
+
years = tr['range']['low']['value'].to_i
|
190
|
+
end
|
191
|
+
|
192
|
+
prefilter.effective_time_offset = 1 + years
|
193
|
+
self.prefilters << prefilter
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def data_criteria_in_population?(population_id, criteria_name)
|
205
|
+
criteria_in_precondition?(self.hqmf_document['population_criteria'][population_id]['preconditions'], criteria_name)
|
206
|
+
end
|
207
|
+
|
208
|
+
def criteria_in_precondition?(preconditions, criteria_name)
|
209
|
+
preconditions.any? do |precondition|
|
210
|
+
(precondition['reference'] == criteria_name) ||
|
211
|
+
(precondition['preconditions'] && criteria_in_precondition?(precondition['preconditions'], criteria_name))
|
212
|
+
end
|
213
|
+
end
|
138
214
|
end
|
139
215
|
end
|
140
|
-
end
|
216
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module HealthDataStandards
|
2
|
+
module CQM
|
3
|
+
class Prefilter
|
4
|
+
include Mongoid::Document
|
5
|
+
# What field on the Record do we want to compare against
|
6
|
+
field :record_field, type: String
|
7
|
+
# greater than, less than, etc.
|
8
|
+
field :comparison, type: String
|
9
|
+
# Is it based on the effective_time, like 65yo during measure period
|
10
|
+
field :effective_time_based, type: Boolean, default: false
|
11
|
+
# If effective_time_based, what is the offset from effective_time in years
|
12
|
+
field :effective_time_offset, type: Integer
|
13
|
+
# Comparison to a plain old value, like gender == 'F'
|
14
|
+
field :desired_value
|
15
|
+
|
16
|
+
embedded_in :measure
|
17
|
+
|
18
|
+
def build_query_hash(effective_time)
|
19
|
+
filter_value = if self.effective_time_based
|
20
|
+
et = Time.at(effective_time)
|
21
|
+
et.years_ago(effective_time_offset).to_i
|
22
|
+
else
|
23
|
+
self.desired_value
|
24
|
+
end
|
25
|
+
|
26
|
+
if self.comparison == '$eq'
|
27
|
+
{self.record_field => desired_value}
|
28
|
+
else
|
29
|
+
{self.record_field => {self.comparison => filter_value}}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -2,7 +2,7 @@ class Record
|
|
2
2
|
include Mongoid::Document
|
3
3
|
include Mongoid::Timestamps
|
4
4
|
extend Memoist
|
5
|
-
|
5
|
+
|
6
6
|
field :title, type: String
|
7
7
|
field :first, type: String
|
8
8
|
field :last, type: String
|
@@ -17,12 +17,13 @@ class Record
|
|
17
17
|
field :test_id, type: Moped::BSON::ObjectId
|
18
18
|
field :marital_status, type: Hash
|
19
19
|
field :medical_record_number, type: String
|
20
|
+
field :medical_record_assigner, type: String
|
20
21
|
field :expired, type: Boolean
|
21
22
|
field :clinicalTrialParticipant, type: Boolean # Currently not implemented in the C32 importer
|
22
23
|
# because it cannot be easily represented in a
|
23
24
|
# HITSP C32
|
24
25
|
|
25
|
-
index "last" => 1
|
26
|
+
index "last" => 1
|
26
27
|
embeds_many :allergies
|
27
28
|
embeds_many :care_goals, class_name: "Entry" # This can be any number of different entry types
|
28
29
|
embeds_many :conditions
|
@@ -50,7 +51,7 @@ class Record
|
|
50
51
|
embeds_many :provider_performances
|
51
52
|
embeds_many :addresses, as: :locatable
|
52
53
|
embeds_many :telecoms, as: :contactable
|
53
|
-
|
54
|
+
|
54
55
|
scope :by_provider, ->(prov, effective_date) { (effective_date) ? where(provider_queries(prov.id, effective_date)) : where('provider_performances.provider_id'=>prov.id) }
|
55
56
|
scope :by_patient_id, ->(id) { where(:medical_record_number => id) }
|
56
57
|
|
@@ -68,7 +69,7 @@ class Record
|
|
68
69
|
def providers
|
69
70
|
provider_performances.map {|pp| pp.provider }
|
70
71
|
end
|
71
|
-
|
72
|
+
|
72
73
|
def over_18?
|
73
74
|
Time.at(birthdate) < Time.now.years_ago(18)
|
74
75
|
end
|
@@ -92,7 +93,7 @@ class Record
|
|
92
93
|
end
|
93
94
|
|
94
95
|
memoize :entries_for_oid
|
95
|
-
|
96
|
+
|
96
97
|
alias :clinical_trial_participant :clinicalTrialParticipant
|
97
98
|
alias :clinical_trial_participant= :clinicalTrialParticipant=
|
98
99
|
|
@@ -139,16 +140,16 @@ class Record
|
|
139
140
|
|
140
141
|
end
|
141
142
|
|
142
|
-
private
|
143
|
-
|
143
|
+
private
|
144
|
+
|
144
145
|
def self.provider_queries(provider_id, effective_date)
|
145
146
|
{'$or' => [provider_query(provider_id, effective_date,effective_date), provider_query(provider_id, nil,effective_date), provider_query(provider_id, effective_date,nil)]}
|
146
147
|
end
|
147
148
|
def self.provider_query(provider_id, start_before, end_after)
|
148
149
|
{'provider_performances' => {'$elemMatch' => {'provider_id' => provider_id, '$and'=>[{'$or'=>[{'start_date'=>nil},{'start_date'=>{'$lt'=>start_before}}]}, {'$or'=>[{'end_date'=>nil},{'end_date'=> {'$gt'=>end_after}}]}] } }}
|
149
150
|
end
|
150
|
-
|
151
151
|
|
152
|
-
|
152
|
+
|
153
|
+
|
153
154
|
|
154
155
|
end
|
@@ -24,14 +24,16 @@ module ThingWithCodes
|
|
24
24
|
if matching_code_sets.present?
|
25
25
|
if value_set_map
|
26
26
|
matching_code_sets.each do |matching_code_set|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
matching_codes = codes_value[matching_code_set] & value_set_map.collect{|cs| cs["set"] == matching_code_set ? cs["values"] : []}.flatten.compact
|
28
|
+
if matching_codes.present?
|
29
|
+
return {'code' => matching_codes.first, 'code_set' => matching_code_set}
|
30
|
+
end
|
31
31
|
end
|
32
|
+
# we did not find a matching preferred code... we cannot write this out to QRDA
|
33
|
+
return nil
|
32
34
|
else
|
33
|
-
|
34
|
-
|
35
|
+
code_set = matching_code_sets.first
|
36
|
+
{'code' => codes_value[code_set].first, 'code_set' => code_set}
|
35
37
|
end
|
36
38
|
else
|
37
39
|
nil
|
@@ -1,13 +1,10 @@
|
|
1
1
|
<recordTarget>
|
2
2
|
<patientRole>
|
3
|
-
|
4
|
-
|
5
|
-
<%
|
6
|
-
|
7
|
-
|
8
|
-
hic = hic.slice(hic.length-9,9)
|
9
|
-
%>
|
10
|
-
<id extension="<%= hic %>A" root="2.16.840.1.113883.4.572"/>
|
3
|
+
<% if (patient.medical_record_number && patient.medical_record_assigner) %>
|
4
|
+
<id extension="<%= patient.medical_record_number %>" root="<%= patient.medical_record_assigner %>"/>
|
5
|
+
<% else -%>
|
6
|
+
<id extension="12345" root="PlaceholderOrganization" />
|
7
|
+
<% end -%>
|
11
8
|
<addr use="HP">
|
12
9
|
<% if patient.addresses.present?
|
13
10
|
patient.addresses.each do |address| -%>
|
@@ -22,7 +22,7 @@
|
|
22
22
|
</assignedAuthoringDevice>
|
23
23
|
<% end %>
|
24
24
|
|
25
|
-
<%== render :partial=>"organization", :locals=>{organization: author.organization} %>
|
25
|
+
<%== render :partial=>"organization", :locals=>{organization: author.organization, tag_name: "representedOrganization"} %>
|
26
26
|
|
27
27
|
</assignedAuthor>
|
28
28
|
</author>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<originalText>Time Difference</originalText>
|
6
6
|
</code>
|
7
7
|
<statusCode code="completed"/>
|
8
|
-
<value xsi:type="PQ" value="<%=
|
8
|
+
<value xsi:type="PQ" value="<%= value %>" unit="min"/>
|
9
9
|
<methodCode code="MEDIAN"
|
10
10
|
displayName="Median"
|
11
11
|
codeSystem="2.16.840.1.113883.5.84"
|
@@ -13,7 +13,7 @@
|
|
13
13
|
<reference typeCode="REFR">
|
14
14
|
<!-- reference to the relevant measure observation in the eMeasure -->
|
15
15
|
<externalObservation classCode="OBS" moodCode="EVN">
|
16
|
-
<id root="<%=
|
16
|
+
<id root="<%= id %>"/>
|
17
17
|
</externalObservation>
|
18
18
|
</reference>
|
19
19
|
</observation>
|
@@ -56,8 +56,16 @@
|
|
56
56
|
</observation>
|
57
57
|
</entryRelationship>
|
58
58
|
<% if population.type == 'MSRPOPL' -%>
|
59
|
-
|
60
|
-
|
59
|
+
<%
|
60
|
+
#need to lookup the observation population entry and then find the stratification entry for it
|
61
|
+
observ = aggregate_count.populations.find{|p| p.type == "OBSERV"}
|
62
|
+
obs_strat = observ.stratifications.find{|s| s.id == strat.id}
|
63
|
+
if obs_strat
|
64
|
+
%>
|
65
|
+
<%== render :partial => 'continuous_variable_value', :locals => {:id => observ.id, :value=>obs_strat.value } %>
|
66
|
+
<%
|
67
|
+
end
|
68
|
+
end -%>
|
61
69
|
<reference typeCode="REFR">
|
62
70
|
<externalObservation classCode="OBS" moodCode="EVN">
|
63
71
|
<id root="<%= strat.id %>"/>
|
@@ -116,7 +124,8 @@
|
|
116
124
|
<% end -%>
|
117
125
|
<% end -%>
|
118
126
|
<% if population.type == 'MSRPOPL' -%>
|
119
|
-
|
127
|
+
<% observ = aggregate_count.populations.find{|p| p.type == "OBSERV"} %>
|
128
|
+
<%== render :partial => 'continuous_variable_value', :locals => {:id => observ.id, :value=>observ.value}%>
|
120
129
|
<% end -%>
|
121
130
|
<reference typeCode="REFR">
|
122
131
|
<externalObservation classCode="OBS" moodCode="EVN">
|
@@ -41,7 +41,6 @@
|
|
41
41
|
<!-- SHALL -->
|
42
42
|
<custodian>
|
43
43
|
<assignedCustodian>
|
44
|
-
<%== render :partial=>"id", :collection=>header.custodian.organization.ids, :id=>"identifier" %>
|
45
44
|
<%== render :partial=>"organization", :locals=>{organization: header.custodian.organization, tag_name: "representedCustodianOrganization"} %>
|
46
45
|
</assignedCustodian>
|
47
46
|
</custodian>
|
@@ -64,7 +63,7 @@
|
|
64
63
|
</name>
|
65
64
|
</assignedPerson>
|
66
65
|
|
67
|
-
<%== render :partial=>"organization", :locals=>{organization: header.legal_authenticator.organization} %>
|
66
|
+
<%== render :partial=>"organization", :locals=>{organization: header.legal_authenticator.organization, tag_name: "representedOrganization"} %>
|
68
67
|
</assignedEntity>
|
69
68
|
</legalAuthenticator>
|
70
69
|
|
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: 3.4.
|
4
|
+
version: 3.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Gregorowicz
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-
|
15
|
+
date: 2014-05-15 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rest-client
|
@@ -286,6 +286,7 @@ files:
|
|
286
286
|
- lib/health-data-standards/models/cqm/bundle.rb
|
287
287
|
- lib/health-data-standards/models/cqm/measure.rb
|
288
288
|
- lib/health-data-standards/models/cqm/patient_cache.rb
|
289
|
+
- lib/health-data-standards/models/cqm/prefilter.rb
|
289
290
|
- lib/health-data-standards/models/cqm/query_cache.rb
|
290
291
|
- lib/health-data-standards/models/encounter.rb
|
291
292
|
- lib/health-data-standards/models/entry.rb
|