health-data-standards 3.4.4 → 3.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -1
- data/lib/health-data-standards/export/rendering_context.rb +1 -3
- data/lib/health-data-standards/export/template_helper.rb +18 -6
- data/lib/health-data-standards/import/cat1/diagnosis_active_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/diagnosis_inactive_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/diagnostic_study_order_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/ecog_status_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/encounter_order_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/encounter_performed_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/gestational_age_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/insurance_provider_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/lab_order_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/lab_result_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/medication_active_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/medication_dispensed_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/patient_importer.rb +32 -30
- data/lib/health-data-standards/import/cat1/procedure_intolerance_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/procedure_order_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/procedure_performed_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/symptom_active_importer.rb +1 -1
- data/lib/health-data-standards/import/cat1/tobacco_use_importer.rb +1 -1
- data/lib/health-data-standards/import/provider_import_utils.rb +6 -7
- data/lib/health-data-standards/models/provider.rb +17 -15
- data/templates/cat1/_record_target.cat1.erb +21 -9
- metadata +38 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68d3be05b049b75724e22b58c9a19635903b9409
|
4
|
+
data.tar.gz: 42ae8b42651d913d9122a4591a6e6789b381ffaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30efed49b0060bba83cc88b4d1eaad0f93bd3fddc01d084d6330bf25884d61c2f0f3b850cabeb153df1a506e7f724d61afd28a6432015a2b826db0abb2181aeb
|
7
|
+
data.tar.gz: 5c500ccd6d7687fdcdfc211b1fbf4d9a47bc8148ff9737f302e5c710dcdf042082312aceeb7f5f55583aa964b619ecd0d0f81fed1bdccdf31db7d3a256de1976
|
data/README.md
CHANGED
@@ -25,11 +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.5 - Not yet released
|
29
|
+
|
30
|
+
* Performance improvents in all exports through template caching
|
31
|
+
* QRDA Cat I export now exports the record's actual address if present
|
32
|
+
* QRDA Cat I export - Bug fix - previously patients with a race but no ethnicity would cause exceptions
|
33
|
+
* QRDA Cat I import - performance improvements through more efficient XPath expressions
|
34
|
+
|
35
|
+
3.4.4 - March 25, 2014
|
29
36
|
|
30
37
|
* Updating the Measure model to deal with continuous variable and NQF and CMS ids through Measure.categories
|
31
38
|
* Bug fix - Filters were not properly handled by the QueryCache
|
32
39
|
* Bug fix - Fixed the order of populations in HQMF::PopulationCriteria::ALL_POPULATION_CODES so that DENEX is after denominator
|
40
|
+
* When importing measure bundles, you can now exclude patients and calculation results
|
33
41
|
|
34
42
|
3.4.3 - March 6, 2014
|
35
43
|
|
@@ -52,9 +52,7 @@ module HealthDataStandards
|
|
52
52
|
rendering_context.extend(extension)
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
56
|
-
eruby.filename= @template_helper.template_file((params[:template] || params[:partial]), params[:partial]).path
|
57
|
-
eruby.result(rendering_context.my_binding)
|
55
|
+
erb.result(rendering_context.my_binding)
|
58
56
|
end.join
|
59
57
|
end
|
60
58
|
end
|
@@ -14,6 +14,7 @@ module HealthDataStandards
|
|
14
14
|
@template_format = template_format
|
15
15
|
@template_directory = template_directory
|
16
16
|
@template_subdir = template_subdir
|
17
|
+
@template_cache = {}
|
17
18
|
end
|
18
19
|
|
19
20
|
def template_root
|
@@ -29,20 +30,31 @@ module HealthDataStandards
|
|
29
30
|
# Returns the raw ERb for the template_name provided. This method will look in
|
30
31
|
# template_directory/template_subdir/template_name.template_format.erb
|
31
32
|
def template(template_name)
|
32
|
-
|
33
|
+
cache_template(template_name)
|
33
34
|
end
|
34
35
|
|
35
36
|
# Basically the same template, but prepends an underscore to the template name
|
36
37
|
# to mimic the Rails convention for template fragments
|
37
38
|
def partial(partial_name)
|
38
|
-
|
39
|
+
cache_template("_#{partial_name}")
|
39
40
|
end
|
40
41
|
|
41
|
-
|
42
|
-
file = partial ? "_#{file}" : file
|
43
|
-
File.new(File.join(template_root, "#{file}.#{@template_format}.erb"))
|
44
|
-
end
|
42
|
+
protected
|
45
43
|
|
44
|
+
def cache_template(template_name)
|
45
|
+
entry = @template_cache[template_name] || {mtime:-1, erb:nil}
|
46
|
+
filename = File.join(template_root, "#{template_name}.#{@template_format}.erb")
|
47
|
+
mtime = File.mtime(filename).to_i
|
48
|
+
if mtime > entry[:mtime]
|
49
|
+
src = File.read(filename)
|
50
|
+
erb = Erubis::EscapedEruby.new(src)
|
51
|
+
erb.filename=filename
|
52
|
+
entry[:mtime]=mtime
|
53
|
+
entry[:erb] = erb
|
54
|
+
@template_cache[template_name]=entry
|
55
|
+
end
|
56
|
+
entry[:erb]
|
57
|
+
end
|
46
58
|
end
|
47
59
|
end
|
48
60
|
end
|
@@ -4,7 +4,7 @@ module HealthDataStandards
|
|
4
4
|
class DiagnosisActiveImporter < CDA::ConditionImporter
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
super(CDA::EntryFinder.new("
|
7
|
+
super(CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.11']"))
|
8
8
|
@status_xpath = nil # We'll hardcode this to active in create entry because this is from the
|
9
9
|
# diagnosis active template
|
10
10
|
@severity_xpath = "./cda:entryRelationship/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.22.4.8']/cda:value"
|
@@ -4,7 +4,7 @@ module HealthDataStandards
|
|
4
4
|
class DiagnosisInactiveImporter < CDA::ConditionImporter
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
super(CDA::EntryFinder.new("
|
7
|
+
super(CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.13']"))
|
8
8
|
@status_xpath = nil # We'll hardcode this to inactive in create entry because this is from the
|
9
9
|
# diagnosis active template
|
10
10
|
end
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class DiagnosticStudyOrderImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.17']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@entry_class = Procedure
|
8
8
|
end
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class EcogStatusImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.103']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@code_xpath = './cda:value'
|
8
8
|
end
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class EncounterOrderImporter < CDA::EncounterImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.22']"))
|
6
6
|
super(entry_finder)
|
7
7
|
end
|
8
8
|
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class EncounterPerformedImporter < CDA::EncounterImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:encounter[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.23']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@reason_xpath = "./cda:entryRelationship[@typeCode='RSON']/cda:observation"
|
8
8
|
end
|
@@ -4,7 +4,7 @@ module HealthDataStandards
|
|
4
4
|
class GestationalAgeImporter < CDA::SectionImporter
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
super(CDA::EntryFinder.new("
|
7
|
+
super(CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.101']"))
|
8
8
|
|
9
9
|
end
|
10
10
|
|
@@ -4,7 +4,7 @@ module HealthDataStandards
|
|
4
4
|
class InsuranceProviderImporter < CDA::SectionImporter
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
super(CDA::EntryFinder.new("
|
7
|
+
super(CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.55']"))
|
8
8
|
@check_for_usable = false # needs to be this way becase InsuranceProvider does not respond
|
9
9
|
# to usable?
|
10
10
|
end
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class LabOrderImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.37']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@entry_class = LabResult
|
8
8
|
end
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class LabResultImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.40']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@entry_class = LabResult
|
8
8
|
end
|
@@ -4,7 +4,7 @@ module HealthDataStandards
|
|
4
4
|
class MedicationActiveImporter < CDA::MedicationImporter
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
super(CDA::EntryFinder.new("
|
7
|
+
super(CDA::EntryFinder.new("./cda:entry/cda:substanceAdministration[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.41']"))
|
8
8
|
end
|
9
9
|
|
10
10
|
def create_entry(entry_element, nrh = CDA::NarrativeReferenceHandler.new)
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class MedicationDispensedImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:supply[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.45']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@code_xpath = "./cda:product/cda:manufacturedProduct/cda:manufacturedMaterial/cda:code"
|
8
8
|
@entry_class = Medication
|
@@ -13,53 +13,53 @@ module HealthDataStandards
|
|
13
13
|
def initialize
|
14
14
|
# This differs from other HDS patient importers in that sections can have multiple importers
|
15
15
|
@section_importers = {}
|
16
|
-
@section_importers[:care_goals] = [generate_importer(CDA::SectionImporter, "
|
16
|
+
@section_importers[:care_goals] = [generate_importer(CDA::SectionImporter, "./cda:entry/cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.1']", '2.16.840.1.113883.3.560.1.9')] #care goal
|
17
17
|
|
18
18
|
@section_importers[:conditions] = [generate_importer(GestationalAgeImporter, nil, '2.16.840.1.113883.3.560.1.1001'),
|
19
19
|
generate_importer(EcogStatusImporter, nil, '2.16.840.1.113883.3.560.1.1001'),
|
20
20
|
generate_importer(SymptomActiveImporter, nil, '2.16.840.1.113883.3.560.1.69', 'active'),
|
21
21
|
generate_importer(DiagnosisActiveImporter, nil, '2.16.840.1.113883.3.560.1.2', 'active'),
|
22
|
-
generate_importer(CDA::ConditionImporter, "
|
23
|
-
generate_importer(CDA::ConditionImporter, "
|
22
|
+
generate_importer(CDA::ConditionImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.54']", '2.16.840.1.113883.3.560.1.404'), # patient characteristic age
|
23
|
+
generate_importer(CDA::ConditionImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.14']", '2.16.840.1.113883.3.560.1.24', 'resolved'), #diagnosis resolved
|
24
24
|
generate_importer(DiagnosisInactiveImporter, nil, '2.16.840.1.113883.3.560.1.23', 'inactive')] #diagnosis inactive
|
25
25
|
|
26
26
|
|
27
|
-
@section_importers[:medications] = [generate_importer(CDA::MedicationImporter, "
|
27
|
+
@section_importers[:medications] = [generate_importer(CDA::MedicationImporter, "./cda:entry/cda:act[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.105']/cda:entryRelationship/cda:substanceAdministration[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.41']", '2.16.840.1.113883.3.560.1.199', 'discharge'), #discharge medication active
|
28
28
|
generate_importer(MedicationActiveImporter, nil, '2.16.840.1.113883.3.560.1.13', 'active'), #medication active
|
29
|
-
generate_importer(CDA::MedicationImporter, "
|
30
|
-
generate_importer(CDA::MedicationImporter, "
|
29
|
+
generate_importer(CDA::MedicationImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.42']/cda:entryRelationship/cda:substanceAdministration[cda:templateId/@root='2.16.840.1.113883.10.20.22.4.16']", '2.16.840.1.113883.3.560.1.14', 'administered'), #medication administered
|
30
|
+
generate_importer(CDA::MedicationImporter, "./cda:entry/cda:substanceAdministration[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.47']", '2.16.840.1.113883.3.560.1.17', 'ordered'), #medication order TODO: ADD NEGATON REASON HANDLING SOMEHOW
|
31
31
|
generate_importer(MedicationDispensedImporter, nil, '2.16.840.1.113883.3.560.1.8', 'dispensed')]
|
32
32
|
|
33
|
-
@section_importers[:procedures] = [generate_importer(CDA::ProcedureImporter, "
|
34
|
-
generate_importer(CDA::ProcedureImporter, "
|
35
|
-
generate_importer(CDA::ProcedureImporter, "
|
36
|
-
generate_importer(CDA::ProcedureImporter, "
|
37
|
-
generate_importer(CDA::ProcedureImporter, "
|
38
|
-
generate_importer(CDA::ProcedureImporter, "
|
39
|
-
generate_importer(CDA::ProcedureImporter, "
|
33
|
+
@section_importers[:procedures] = [generate_importer(CDA::ProcedureImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.59']", '2.16.840.1.113883.3.560.1.57', 'performed'), #physical exam performed
|
34
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.3']", '2.16.840.1.113883.3.560.1.131'), #comm from provider to patient
|
35
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.31']", '2.16.840.1.113883.3.560.1.45', 'ordered'), #intervention ordered
|
36
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.32']", '2.16.840.1.113883.3.560.1.46', 'performed'), #intervention performed
|
37
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.34']", '2.16.840.1.113883.3.560.1.47'), #intervention result
|
38
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/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
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/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(ProcedurePerformedImporter, "
|
42
|
-
generate_importer(CDA::ProcedureImporter, "
|
43
|
-
generate_importer(CDA::ProcedureImporter, "
|
44
|
-
generate_importer(CDA::ProcedureImporter, "
|
41
|
+
generate_importer(ProcedurePerformedImporter, "./cda:entry/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
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/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
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.69']", '2.16.840.1.113883.3.560.1.21'), #risk category assessment
|
44
|
+
generate_importer(CDA::ProcedureImporter, "./cda:entry/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
|
45
45
|
generate_importer(DiagnosticStudyOrderImporter, nil, '2.16.840.1.113883.3.560.1.40', 'ordered')]
|
46
46
|
|
47
47
|
@section_importers[:allergies] = [generate_importer(ProcedureIntoleranceImporter, nil, '2.16.840.1.113883.3.560.1.61'),
|
48
|
-
generate_importer(CDA::AllergyImporter, "
|
49
|
-
generate_importer(CDA::AllergyImporter, "
|
50
|
-
generate_importer(CDA::AllergyImporter, "
|
48
|
+
generate_importer(CDA::AllergyImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.46']", '2.16.840.1.113883.3.560.1.67'), #medication intolerance
|
49
|
+
generate_importer(CDA::AllergyImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.43']", '2.16.840.1.113883.3.560.1.7'), #medication adverse effect
|
50
|
+
generate_importer(CDA::AllergyImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.44']", '2.16.840.1.113883.3.560.1.1')] #medication allergy
|
51
51
|
|
52
|
-
@section_importers[:medical_equipment] = [generate_importer(CDA::MedicalEquipmentImporter, "
|
52
|
+
@section_importers[:medical_equipment] = [generate_importer(CDA::MedicalEquipmentImporter, "./cda:entry/cda:procedure[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.7']", '2.16.840.1.113883.3.560.1.110', 'applied')]
|
53
53
|
|
54
54
|
@section_importers[:results] = [generate_importer(LabOrderImporter, nil, '2.16.840.1.113883.3.560.1.50', 'ordered'), #lab ordered
|
55
|
-
generate_importer(CDA::ResultImporter, "
|
56
|
-
generate_importer(CDA::ResultImporter, "
|
57
|
-
generate_importer(CDA::ResultImporter, "
|
58
|
-
generate_importer(CDA::ResultImporter, "
|
59
|
-
generate_importer(CDA::ResultImporter, "
|
55
|
+
generate_importer(CDA::ResultImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.38']", '2.16.840.1.113883.3.560.1.5', 'performed'), #lab performed
|
56
|
+
generate_importer(CDA::ResultImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.34']", '2.16.840.1.113883.3.560.1.47'), #intervention result
|
57
|
+
generate_importer(CDA::ResultImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.57']", '2.16.840.1.113883.3.560.1.18'), #physical exam finding
|
58
|
+
generate_importer(CDA::ResultImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.28']", '2.16.840.1.113883.3.560.1.88'), #functional status result
|
59
|
+
generate_importer(CDA::ResultImporter, "./cda:entry/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(EncounterPerformedImporter, "
|
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')]
|
@@ -79,22 +79,24 @@ module HealthDataStandards
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def import_sections(record, doc)
|
82
|
+
|
83
|
+
context = doc.xpath("/cda:ClinicalDocument/cda:component/cda:structuredBody/cda:component/cda:section[cda:templateId/@root = '2.16.840.1.113883.10.20.24.2.1']")
|
82
84
|
nrh = CDA::NarrativeReferenceHandler.new
|
83
85
|
nrh.build_id_map(doc)
|
84
86
|
@section_importers.each do |section, entry_packages|
|
85
87
|
entry_packages.each do |entry_package|
|
86
|
-
record.send(section) << entry_package.package_entries(
|
88
|
+
record.send(section) << entry_package.package_entries(context, nrh)
|
87
89
|
end
|
88
90
|
end
|
89
91
|
end
|
90
92
|
|
91
93
|
def get_clinical_trial_participant(record, doc)
|
92
|
-
entry_elements = doc.xpath("
|
94
|
+
entry_elements = doc.xpath("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.51']")
|
93
95
|
record.clinicalTrialParticipant = true unless entry_elements.blank?
|
94
96
|
end
|
95
97
|
|
96
98
|
def get_patient_expired(record, doc)
|
97
|
-
entry_elements = doc.xpath("
|
99
|
+
entry_elements = doc.xpath("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.54']")
|
98
100
|
record.expired = true unless entry_elements.empty?
|
99
101
|
end
|
100
102
|
|
@@ -4,7 +4,7 @@ module HealthDataStandards
|
|
4
4
|
class ProcedureIntoleranceImporter < CDA::SectionImporter
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
super(CDA::EntryFinder.new("
|
7
|
+
super(CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.62']/cda:entryRelationship/cda:procedure[cda:templateId/@root='2.16.840.1.113883.10.20.24.3.64']"))
|
8
8
|
@entry_class = Allergy
|
9
9
|
end
|
10
10
|
end
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class ProcedureOrderImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:procedure[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.63']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@entry_class = Procedure
|
8
8
|
end
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class ProcedurePerformedImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
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
7
|
@entry_class = Procedure
|
8
8
|
@ordinality_xpath = "./cda:priorityCode"
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class SymptomActiveImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.76']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@code_xpath = './cda:value'
|
8
8
|
end
|
@@ -2,7 +2,7 @@ module HealthDataStandards
|
|
2
2
|
module Import
|
3
3
|
module Cat1
|
4
4
|
class TobaccoUseImporter < CDA::SectionImporter
|
5
|
-
def initialize(entry_finder=CDA::EntryFinder.new("
|
5
|
+
def initialize(entry_finder=CDA::EntryFinder.new("./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.22.4.85']"))
|
6
6
|
super(entry_finder)
|
7
7
|
@entry_class = Entry
|
8
8
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module ProviderImportUtils
|
2
|
-
|
2
|
+
|
3
3
|
def extract_provider(performer, element_name="assignedEntity")
|
4
4
|
provider_data = extract_provider_data(performer, false, "./cda:#{element_name}")
|
5
5
|
find_or_create_provider(provider_data)
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def find_or_create_provider(provider_hash)
|
9
9
|
provider = Provider.by_npi(provider_hash[:npi]).first if provider_hash[:npi] && !provider_hash[:npi].empty?
|
10
10
|
unless provider
|
@@ -12,8 +12,6 @@ module ProviderImportUtils
|
|
12
12
|
provider = Provider.create(provider_hash)
|
13
13
|
provider.npi = provider_hash[:npi]
|
14
14
|
else
|
15
|
-
provider ||= Provider.resolve_provider(provider_hash) if Provider.respond_to? :resolve_provider
|
16
|
-
|
17
15
|
ident_roots = provider_hash[:cda_identifiers].map {|ident| ident.root}
|
18
16
|
ident_extensions = provider_hash[:cda_identifiers].map {|ident| ident.extension}
|
19
17
|
unless ident_roots.size == 0
|
@@ -24,10 +22,11 @@ module ProviderImportUtils
|
|
24
22
|
:family_name=> provider_hash[:family_name],
|
25
23
|
:specialty => provider_hash[:specialty]}
|
26
24
|
provider ||= Provider.where(provider_query).first
|
25
|
+
provider ||= Provider.resolve_provider(provider_hash)
|
27
26
|
provider ||= Provider.create(provider_hash)
|
28
27
|
end
|
29
28
|
end
|
30
|
-
provider
|
29
|
+
provider
|
31
30
|
end
|
32
31
|
|
33
32
|
# Returns nil if result is an empty string, block allows text munging of result if there is one
|
@@ -39,5 +38,5 @@ module ProviderImportUtils
|
|
39
38
|
result.content
|
40
39
|
end
|
41
40
|
end
|
42
|
-
|
43
|
-
end
|
41
|
+
|
42
|
+
end
|
@@ -7,9 +7,9 @@ class Provider
|
|
7
7
|
|
8
8
|
field :specialty , type: String
|
9
9
|
field :phone , type: String
|
10
|
-
|
10
|
+
|
11
11
|
validates_uniqueness_of :npi, allow_blank: true
|
12
|
-
|
12
|
+
|
13
13
|
embeds_one :organization
|
14
14
|
embeds_many :cda_identifiers, class_name: "CDAIdentifier", as: :cda_identifiable
|
15
15
|
|
@@ -42,21 +42,21 @@ class Provider
|
|
42
42
|
def records(effective_date=nil)
|
43
43
|
Record.by_provider(self, effective_date)
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
# validate the NPI, should be 10 or 15 digits total with the final digit being a
|
47
47
|
# checksum using the Luhn algorithm with additional special handling as described in
|
48
|
-
# https://www.cms.gov/NationalProvIdentStand/Downloads/NPIcheckdigit.pdf
|
48
|
+
# https://www.cms.gov/NationalProvIdentStand/Downloads/NPIcheckdigit.pdf
|
49
49
|
def self.valid_npi?(npi)
|
50
50
|
return false unless npi
|
51
51
|
return false if npi.length != 10 and npi.length != 15
|
52
52
|
return false if npi.gsub(/\d/, '').length > 0 # npi must be all digits
|
53
53
|
return false if npi.length == 15 and (npi =~ /^80840/)==nil # 15 digit npi must start with 80840
|
54
|
-
|
54
|
+
|
55
55
|
# checksum is always calculated as if 80840 prefix is present
|
56
56
|
if npi.length==10
|
57
57
|
npi = '80840'+npi
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
return luhn_checksum(npi[0,14])==npi[14]
|
61
61
|
end
|
62
62
|
|
@@ -72,17 +72,19 @@ class Provider
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
sum = (9*sum)%10
|
75
|
-
|
75
|
+
|
76
76
|
return sum.to_s
|
77
77
|
end
|
78
78
|
|
79
|
-
#
|
80
|
-
#
|
81
|
-
# npi number associated with it. This allows applications to handle
|
82
|
-
# this
|
83
|
-
#
|
84
|
-
#
|
79
|
+
# When using the ProviderImporter class this method will be called if a parsed
|
80
|
+
# provider can not be found in the database if the parsed provider does not
|
81
|
+
# have an npi number associated with it. This allows applications to handle
|
82
|
+
# this how they see fit by redefining this method. The default implementation
|
83
|
+
# is to return an orphan parent (the singular provider without an NPI) if one
|
84
|
+
# exists. If this method call return nil an attempt will be made to discover
|
85
|
+
# the Provider by name matching and if that fails a Provider will be created
|
86
|
+
# in the db based on the information in the parsed hash.
|
85
87
|
def self.resolve_provider(provider_hash)
|
86
|
-
|
88
|
+
Provider.where(:npi => nil).first
|
87
89
|
end
|
88
|
-
end
|
90
|
+
end
|
@@ -2,18 +2,30 @@
|
|
2
2
|
<patientRole>
|
3
3
|
<!-- id root="Cypress" extension="<%= patient.id %>"/ -->
|
4
4
|
<!-- Fake Medicare HIC number -->
|
5
|
-
<%
|
5
|
+
<%
|
6
6
|
# get the pateint id , treate it as a hex number, turn it to a string and strip the last 9 characters off of it
|
7
7
|
hic = patient.id.to_s.hex.to_s
|
8
8
|
hic = hic.slice(hic.length-9,9)
|
9
9
|
%>
|
10
10
|
<id extension="<%= hic %>A" root="2.16.840.1.113883.4.572"/>
|
11
11
|
<addr use="HP">
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
<% if patient.addresses.present?
|
13
|
+
patient.addresses.each do |address| -%>
|
14
|
+
<% address.street.each do |street| -%>
|
15
|
+
<streetAddressLine><%= street %></streetAddressLine>
|
16
|
+
<% end %>
|
17
|
+
<city><%= address.city %></city>
|
18
|
+
<state><%= address.state %></state>
|
19
|
+
<postalCode><%= address.zip %></postalCode>
|
20
|
+
<country><%= address.country %></country>
|
21
|
+
<% end -%>
|
22
|
+
<% else -%>
|
23
|
+
<streetAddressLine>202 Burlington Rd.</streetAddressLine>
|
24
|
+
<city>Bedford</city>
|
25
|
+
<state>MA</state>
|
26
|
+
<postalCode>01730</postalCode>
|
27
|
+
<country>US</country>
|
28
|
+
<% end -%>
|
17
29
|
</addr>
|
18
30
|
<telecom use="WP" value="tel:+1-781-271-3000"/>
|
19
31
|
<patient>
|
@@ -26,11 +38,11 @@
|
|
26
38
|
<% if (patient.race) %>
|
27
39
|
<raceCode code="<%= patient.race['code'] %>" <% if patient.race['name']%>displayName="<%= patient.race['name'] %>"<% end %> codeSystemName="CDC Race and Ethnicity" codeSystem="2.16.840.1.113883.6.238"/>
|
28
40
|
<% end %>
|
29
|
-
<% if (patient.
|
41
|
+
<% if (patient.ethnicity) %>
|
30
42
|
<ethnicGroupCode code="<%= patient.ethnicity['code'] %>" <% if patient.ethnicity['name']%>displayName="<%= patient.ethnicity['name'] %>"<% end %> codeSystemName="CDC Race and Ethnicity" codeSystem="2.16.840.1.113883.6.238"/>
|
31
43
|
<% end %>
|
32
44
|
<%
|
33
|
-
languages = patient.languages
|
45
|
+
languages = patient.languages
|
34
46
|
languages = ["eng"] if languages.nil? or languages.empty?
|
35
47
|
languages.each do |language|%>
|
36
48
|
<languageCommunication>
|
@@ -41,4 +53,4 @@
|
|
41
53
|
<% end %>
|
42
54
|
</patient>
|
43
55
|
</patientRole>
|
44
|
-
</recordTarget>
|
56
|
+
</recordTarget>
|
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.5
|
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-04-04 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rest-client
|
@@ -175,6 +175,10 @@ executables: []
|
|
175
175
|
extensions: []
|
176
176
|
extra_rdoc_files: []
|
177
177
|
files:
|
178
|
+
- Gemfile
|
179
|
+
- README.md
|
180
|
+
- Rakefile
|
181
|
+
- lib/health-data-standards.rb
|
178
182
|
- lib/health-data-standards/export/c32.rb
|
179
183
|
- lib/health-data-standards/export/cat_1.rb
|
180
184
|
- lib/health-data-standards/export/cat_3.rb
|
@@ -191,6 +195,7 @@ files:
|
|
191
195
|
- lib/health-data-standards/export/helper/scooped_view_helper.rb
|
192
196
|
- lib/health-data-standards/export/html.rb
|
193
197
|
- lib/health-data-standards/export/qrda/entry_template_resolver.rb
|
198
|
+
- lib/health-data-standards/export/qrda/hqmf-qrda-oids.json
|
194
199
|
- lib/health-data-standards/export/rendering_context.rb
|
195
200
|
- lib/health-data-standards/export/template_helper.rb
|
196
201
|
- lib/health-data-standards/export/view_helper.rb
|
@@ -325,22 +330,51 @@ files:
|
|
325
330
|
- lib/health-data-standards/models/treating_provider.rb
|
326
331
|
- lib/health-data-standards/models/vital_sign.rb
|
327
332
|
- lib/health-data-standards/railtie.rb
|
333
|
+
- lib/health-data-standards/tasks/bundle.rake
|
328
334
|
- lib/health-data-standards/util/code_system_helper.rb
|
329
335
|
- lib/health-data-standards/util/hl7_helper.rb
|
330
336
|
- lib/health-data-standards/util/hqmf_template_helper.rb
|
337
|
+
- lib/health-data-standards/util/hqmf_template_oid_map.json
|
331
338
|
- lib/health-data-standards/util/vs_api.rb
|
332
|
-
- lib/
|
339
|
+
- lib/hqmf-generator/attribute.xml.erb
|
340
|
+
- lib/hqmf-generator/characteristic_criteria.xml.erb
|
341
|
+
- lib/hqmf-generator/code.xml.erb
|
342
|
+
- lib/hqmf-generator/condition_criteria.xml.erb
|
343
|
+
- lib/hqmf-generator/derivation.xml.erb
|
344
|
+
- lib/hqmf-generator/description.xml.erb
|
345
|
+
- lib/hqmf-generator/document.xml.erb
|
346
|
+
- lib/hqmf-generator/effective_time.xml.erb
|
347
|
+
- lib/hqmf-generator/encounter_criteria.xml.erb
|
348
|
+
- lib/hqmf-generator/field.xml.erb
|
333
349
|
- lib/hqmf-generator/hqmf-generator.rb
|
350
|
+
- lib/hqmf-generator/observation_criteria.xml.erb
|
351
|
+
- lib/hqmf-generator/population_criteria.xml.erb
|
352
|
+
- lib/hqmf-generator/precondition.xml.erb
|
353
|
+
- lib/hqmf-generator/procedure_criteria.xml.erb
|
354
|
+
- lib/hqmf-generator/reason.xml.erb
|
355
|
+
- lib/hqmf-generator/reference.xml.erb
|
356
|
+
- lib/hqmf-generator/source.xml.erb
|
357
|
+
- lib/hqmf-generator/specific_occurrence.xml.erb
|
358
|
+
- lib/hqmf-generator/subset.xml.erb
|
359
|
+
- lib/hqmf-generator/substance_criteria.xml.erb
|
360
|
+
- lib/hqmf-generator/supply_criteria.xml.erb
|
361
|
+
- lib/hqmf-generator/template_id.xml.erb
|
362
|
+
- lib/hqmf-generator/temporal_relationship.xml.erb
|
363
|
+
- lib/hqmf-generator/value.xml.erb
|
364
|
+
- lib/hqmf-generator/variable_criteria.xml.erb
|
334
365
|
- lib/hqmf-model/attribute.rb
|
366
|
+
- lib/hqmf-model/data_criteria.json
|
335
367
|
- lib/hqmf-model/data_criteria.rb
|
336
368
|
- lib/hqmf-model/document.rb
|
337
369
|
- lib/hqmf-model/population_criteria.rb
|
338
370
|
- lib/hqmf-model/precondition.rb
|
339
371
|
- lib/hqmf-model/types.rb
|
340
372
|
- lib/hqmf-model/utilities.rb
|
373
|
+
- lib/hqmf-parser.rb
|
341
374
|
- lib/hqmf-parser/1.0/attribute.rb
|
342
375
|
- lib/hqmf-parser/1.0/comparison.rb
|
343
376
|
- lib/hqmf-parser/1.0/data_criteria.rb
|
377
|
+
- lib/hqmf-parser/1.0/data_criteria_oid_xpath.json
|
344
378
|
- lib/hqmf-parser/1.0/document.rb
|
345
379
|
- lib/hqmf-parser/1.0/expression.rb
|
346
380
|
- lib/hqmf-parser/1.0/observation.rb
|
@@ -368,7 +402,6 @@ files:
|
|
368
402
|
- lib/hqmf-parser/converter/pass2/comparison_converter.rb
|
369
403
|
- lib/hqmf-parser/converter/pass2/operator_converter.rb
|
370
404
|
- lib/hqmf-parser/parser.rb
|
371
|
-
- lib/hqmf-parser.rb
|
372
405
|
- lib/util/counter.rb
|
373
406
|
- templates/_author.hdata.erb
|
374
407
|
- templates/_pedigree.hdata.erb
|
@@ -503,39 +536,6 @@ files:
|
|
503
536
|
- templates/html/_section.html.erb
|
504
537
|
- templates/html/show.html.erb
|
505
538
|
- templates/metadata.hdata.erb
|
506
|
-
- lib/health-data-standards/export/qrda/hqmf-qrda-oids.json
|
507
|
-
- lib/health-data-standards/util/hqmf_template_oid_map.json
|
508
|
-
- lib/hqmf-model/data_criteria.json
|
509
|
-
- lib/hqmf-parser/1.0/data_criteria_oid_xpath.json
|
510
|
-
- lib/hqmf-generator/attribute.xml.erb
|
511
|
-
- lib/hqmf-generator/characteristic_criteria.xml.erb
|
512
|
-
- lib/hqmf-generator/code.xml.erb
|
513
|
-
- lib/hqmf-generator/condition_criteria.xml.erb
|
514
|
-
- lib/hqmf-generator/derivation.xml.erb
|
515
|
-
- lib/hqmf-generator/description.xml.erb
|
516
|
-
- lib/hqmf-generator/document.xml.erb
|
517
|
-
- lib/hqmf-generator/effective_time.xml.erb
|
518
|
-
- lib/hqmf-generator/encounter_criteria.xml.erb
|
519
|
-
- lib/hqmf-generator/field.xml.erb
|
520
|
-
- lib/hqmf-generator/observation_criteria.xml.erb
|
521
|
-
- lib/hqmf-generator/population_criteria.xml.erb
|
522
|
-
- lib/hqmf-generator/precondition.xml.erb
|
523
|
-
- lib/hqmf-generator/procedure_criteria.xml.erb
|
524
|
-
- lib/hqmf-generator/reason.xml.erb
|
525
|
-
- lib/hqmf-generator/reference.xml.erb
|
526
|
-
- lib/hqmf-generator/source.xml.erb
|
527
|
-
- lib/hqmf-generator/specific_occurrence.xml.erb
|
528
|
-
- lib/hqmf-generator/subset.xml.erb
|
529
|
-
- lib/hqmf-generator/substance_criteria.xml.erb
|
530
|
-
- lib/hqmf-generator/supply_criteria.xml.erb
|
531
|
-
- lib/hqmf-generator/template_id.xml.erb
|
532
|
-
- lib/hqmf-generator/temporal_relationship.xml.erb
|
533
|
-
- lib/hqmf-generator/value.xml.erb
|
534
|
-
- lib/hqmf-generator/variable_criteria.xml.erb
|
535
|
-
- lib/health-data-standards/tasks/bundle.rake
|
536
|
-
- Gemfile
|
537
|
-
- README.md
|
538
|
-
- Rakefile
|
539
539
|
homepage: https://github.com/projectcypress/health-data-standards
|
540
540
|
licenses:
|
541
541
|
- APL 2.0
|
@@ -556,7 +556,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
556
556
|
version: '0'
|
557
557
|
requirements: []
|
558
558
|
rubyforge_project:
|
559
|
-
rubygems_version: 2.
|
559
|
+
rubygems_version: 2.2.2
|
560
560
|
signing_key:
|
561
561
|
specification_version: 4
|
562
562
|
summary: A library for generating and consuming various healthcare related formats.
|