cqm-reports 1.0.0.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: faad9a8a2c63b2c26bd1ed689be3cea13a54bc520e9fbcf95a56550b2646a095
4
- data.tar.gz: cb7867e3555e19a454dc918ef7f018672f177cf3b3eeeef124aff46723693c56
3
+ metadata.gz: 9f52ee70f2be4c43ccf9c3d918ed805a323d942d1768d5621967c9232ea303c5
4
+ data.tar.gz: c866224aca04b6760a35a3fd0f8d78e03c5fe85d9bff0a4d41a8af907eebf995
5
5
  SHA512:
6
- metadata.gz: 16ad11bbe2c9131f6977c8eac6b06150f6fb22f4a465364f40e65375e3271cbf241d4777b0ae3cad8fecd0bb0a8a1808957c9f813c761024851a44c05cc530ea
7
- data.tar.gz: 5c2710035d5e2b6c56e3e25c974b5ecefc131fa5fb058c1b3ed2ad09825639a937f6a75811bd3286fb95364c69d64dcfa45d8778f2875c290d94c5609f46c852
6
+ metadata.gz: 42797a2e8c76511344a48f803034e6d5bc4bf1468b5fcd8853f53a10cea295413a96fea7299767dbfcef6b0cf7663e9f9e648715c3f3c7bb412e09391e08bb68
7
+ data.tar.gz: 94dc517b00e37117d00eea8ca516103bc3fa21af59457c7697e4299a4d2c92d8f46090fca4103cdfdbaede0aa6e130e3a52e3af1395564d447ccff712959cbd7
@@ -2,7 +2,7 @@
2
2
  <div class="div-table-body">
3
3
  {{#dataElementCodes}}
4
4
  <div class="div-head-row">
5
- <div class="div-table-head--no-border"><span class="criteria-heading">{{codeSystem}}:</span> {{code}}</div>
5
+ <div class="div-table-head--no-border"><span class="criteria-heading">{{{code_system_name}}}:</span> {{code}}</div>
6
6
  </div>
7
7
  {{/dataElementCodes}}
8
8
  </div>
@@ -27,7 +27,11 @@ class QdmPatient < Mustache
27
27
  end
28
28
 
29
29
  def code_code_system_string
30
- "#{self['code']} (#{self['codeSystem']})"
30
+ "#{self['code']} (#{HQMF::Util::CodeSystemHelper.code_system_for(self['codeSystemOid'])})"
31
+ end
32
+
33
+ def code_system_name
34
+ HQMF::Util::CodeSystemHelper.code_system_for(self['codeSystemOid'])
31
35
  end
32
36
 
33
37
  def result_string
@@ -3,6 +3,8 @@
3
3
  <typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/>
4
4
  <!-- US Realm Header Template Id -->
5
5
  <templateId root="2.16.840.1.113883.10.20.27.1.1" extension="2017-06-01"/>
6
+ <!-- QRDA Category III Report - CMS (V4) -->
7
+ <templateId root="2.16.840.1.113883.10.20.27.1.2" extension="2019-05-01"/>
6
8
  <!-- This is the globally unique identifier for this QRDA document -->
7
9
  <id root="{{random_id}}"/>
8
10
  <!-- QRDA III document type code -->
@@ -21,5 +23,10 @@
21
23
  </recordTarget>
22
24
  {{> qrda_header/_author}}
23
25
  {{> qrda_header/_custodian}}
26
+ {{> qrda_header/_information_recipient}}
24
27
  {{> qrda_header/_legal_authenticator}}
28
+ {{#cpcplus?}}
29
+ {{> qrda_header/_participant_location}}
30
+ {{/cpcplus?}}
31
+ {{> qrda_header/_participant_ehr}}
25
32
  {{> qrda_header/_documentation_of_service_event}}
@@ -5,6 +5,8 @@
5
5
  <observation classCode="OBS" moodCode="EVN">
6
6
  <!-- Measure Data template -->
7
7
  <templateId root="2.16.840.1.113883.10.20.27.3.5" extension="2016-09-01"/>
8
+ <!-- Measure Data - CMS (V4) -->
9
+ <templateId root="2.16.840.1.113883.10.20.27.3.16" extension="2019-05-01"/>
8
10
  <code code="ASSERTION" codeSystem="2.16.840.1.113883.5.4" displayName="Assertion" codeSystemName="ActCode"/>
9
11
  <statusCode code="completed"/>
10
12
  <value xsi:type="CD" code="{{population_type}}" codeSystem="2.16.840.1.113883.5.4" codeSystemName="ActCode"/>
@@ -10,6 +10,8 @@
10
10
  <!-- In this case the query is using an eMeasure -->
11
11
  <!-- QRDA Category III Measure Section template -->
12
12
  <templateId extension="2017-06-01" root="2.16.840.1.113883.10.20.27.2.1"/>
13
+ <!-- QRDA Category III Measure Section - CMS (V4) -->
14
+ <templateId extension="2019-05-01" root="2.16.840.1.113883.10.20.27.2.3"/>
13
15
  <code code="55186-1" codeSystem="2.16.840.1.113883.6.1"/>
14
16
  <title>Measure Section</title>
15
17
  <text>
@@ -39,6 +41,7 @@
39
41
  <templateId root="2.16.840.1.113883.10.20.24.3.98"/>
40
42
  <!-- SHALL 1..* (one for each referenced measure) Measure Reference and Results template -->
41
43
  <templateId extension="2016-09-01" root="2.16.840.1.113883.10.20.27.3.1"/>
44
+ <templateId extension="2019-05-01" root="2.16.840.1.113883.10.20.27.3.17"/>
42
45
  <id extension="{{random_id}}" root="1.3.6.1.4.1.115"/>
43
46
  <statusCode code="completed"/>
44
47
  <!-- Containing isBranch external references -->
@@ -13,7 +13,14 @@
13
13
  <value xsi:type="CD" nullFlavor="UNK" />
14
14
  {{/unknown_supplemental_value?}}
15
15
  {{^unknown_supplemental_value?}}
16
- <value xsi:type="CD" code="{{code}}" codeSystem="{{supplemental_data_value_code_system}}"/>
16
+ {{#payer_code?}}
17
+ <value xsi:type="CD" nullFlavor="OTH">
18
+ <translation code="{{{cms_payer_code}}}" codeSystem="2.16.840.1.113883.3.249.12" codeSystemName="CMS Clinical Codes"/>
19
+ </value>
20
+ {{/payer_code?}}
21
+ {{^payer_code?}}
22
+ <value xsi:type="CD" code="{{code}}" codeSystem="{{supplemental_data_value_code_system}}"/>
23
+ {{/payer_code?}}
17
24
  {{/unknown_supplemental_value?}}
18
25
  <entryRelationship typeCode="SUBJ" inversionInd="true">
19
26
  <!-- Aggregate Count template -->
@@ -4,7 +4,6 @@
4
4
  {{> _header}}
5
5
  <component>
6
6
  <structuredBody>
7
- {{> _reporting_period}}
8
7
  {{> _measure_section}}
9
8
  </structuredBody>
10
9
  </component>
@@ -6,6 +6,8 @@ class Qrda3R21 < Mustache
6
6
 
7
7
  self.template_path = __dir__
8
8
 
9
+ PAYER_MAP = { '1' => 'A', '2' => 'B', '3' => 'D', '4' => 'D', '5' => 'C', '6' => 'C', '7' => 'D', '8' => 'D', '9' => 'D' }.freeze
10
+
9
11
  def initialize(aggregate_results, measures, options = {})
10
12
  @aggregate_results = aggregate_results
11
13
  @measures = measures
@@ -75,10 +77,23 @@ class Qrda3R21 < Mustache
75
77
  when 'SEX'
76
78
  [{ tid: '2.16.840.1.113883.10.20.27.3.6', extension: '2016-09-01' }]
77
79
  when 'PAYER'
78
- [{ tid: '2.16.840.1.113883.10.20.27.3.9', extension: '2016-02-01' }]
80
+ [{ tid: '2.16.840.1.113883.10.20.27.3.9', extension: '2016-02-01' },
81
+ { tid: '2.16.840.1.113883.10.20.27.3.18', extension: '2018-05-01' }]
79
82
  end
80
83
  end
81
84
 
85
+ def cms_payer_code
86
+ PAYER_MAP[self['code'][0]] || 'D'
87
+ end
88
+
89
+ def cpcplus?
90
+ @submission_program == 'CPCPLUS'
91
+ end
92
+
93
+ def payer_code?
94
+ self['type'] == 'PAYER'
95
+ end
96
+
82
97
  def supplemental_data_code
83
98
  case self['type']
84
99
  when 'RACE'
@@ -0,0 +1,7 @@
1
+ {{#submission_program}}
2
+ <informationRecipient>
3
+ <intendedRecipient>
4
+ <id extension="{{submission_program}}" root="2.16.840.1.113883.3.249.7"/>
5
+ </intendedRecipient>
6
+ </informationRecipient>
7
+ {{/submission_program}}
@@ -0,0 +1,6 @@
1
+ <participant typeCode="DEV">
2
+ <associatedEntity classCode="RGPR">
3
+ <id root="2.16.840.1.113883.3.2074.1" extension="12345abcde67890"/>
4
+ <code code="129465004" displayName="medical record, device" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED-CT"/>
5
+ </associatedEntity>
6
+ </participant>
@@ -0,0 +1,13 @@
1
+ <participant typeCode="LOC">
2
+ <associatedEntity classCode="SDLOC">
3
+ <id root="2.16.840.1.113883.3.249.5.1" extension="T2OR1234" assigningAuthorityName="CMS-CMMI"/>
4
+ <code code="394730007" displayName="healthcare related organization" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED-CT"/>
5
+ <addr>
6
+ <streetAddressLine>202 Burlington Rd.</streetAddressLine>
7
+ <city>Bedford</city>
8
+ <state>MA</state>
9
+ <postalCode>01730</postalCode>
10
+ <country>US</country>
11
+ </addr>
12
+ </associatedEntity>
13
+ </participant>
@@ -27,28 +27,26 @@ module Qrda
27
27
  "<id nullFlavor=\"NA\"/>"
28
28
  end
29
29
 
30
- def code_system_oid(data_element_code)
31
- data_element_code['codeSystemOid'] || HQMF::Util::CodeSystemHelper.oid_for_code_system(data_element_code['codeSystem'])
32
- end
33
-
34
30
  def code_and_codesystem
35
- if self['codeSystem'] == 'NA_VALUESET'
31
+ oid = self['codeSystemOid'] || self['codeSystem']
32
+ if oid == '1.2.3.4.5.6.7.8.9.10'
36
33
  "nullFlavor=\"NA\" sdtc:valueSet=\"#{self['code']}\""
37
34
  else
38
- "code=\"#{self['code']}\" codeSystem=\"#{code_system_oid(self)}\" codeSystemName=\"#{self['codeSystem']}\""
35
+ "code=\"#{self['code']}\" codeSystem=\"#{oid}\" codeSystemName=\"#{HQMF::Util::CodeSystemHelper.code_system_for(oid)}\""
39
36
  end
40
37
  end
41
38
 
42
39
  def primary_code_and_codesystem
43
- "code=\"#{self[:dataElementCodes][0]['code']}\" codeSystem=\"#{code_system_oid(self[:dataElementCodes][0])}\" codeSystemName=\"#{self[:dataElementCodes][0]['codeSystem']}\""
40
+ oid = self[:dataElementCodes][0]['codeSystemOid'] || self[:dataElementCodes][0]['codeSystem']
41
+ "code=\"#{self[:dataElementCodes][0]['code']}\" codeSystem=\"#{oid}\" codeSystemName=\"#{HQMF::Util::CodeSystemHelper.code_system_for(oid)}\""
44
42
  end
45
43
 
46
44
  def translation_codes_and_codesystem_list
47
45
  translation_list = ""
48
46
  self[:dataElementCodes].each_with_index do |_dec, index|
49
47
  next if index.zero?
50
-
51
- translation_list += "<translation code=\"#{self[:dataElementCodes][index]['code']}\" codeSystem=\"#{code_system_oid(self[:dataElementCodes][index])}\" codeSystemName=\"#{self[:dataElementCodes][index]['codeSystem']}\"/>"
48
+ oid = self[:dataElementCodes][index]['codeSystemOid'] || self[:dataElementCodes][index]['codeSystem']
49
+ translation_list += "<translation code=\"#{self[:dataElementCodes][index]['code']}\" codeSystem=\"#{oid}\" codeSystemName=\"#{HQMF::Util::CodeSystemHelper.code_system_for(oid)}\"/>"
52
50
  end
53
51
  translation_list
54
52
  end
@@ -68,7 +66,8 @@ module Qrda
68
66
 
69
67
  def result_value_as_string(result)
70
68
  return "<value xsi:type=\"CD\" nullFlavor=\"UNK\"/>" unless result
71
- return "<value xsi:type=\"CD\" code=\"#{result['code']}\" codeSystem=\"#{code_system_oid(result)}\" codeSystemName=\"#{result['codeSystem']}\"/>" if result['code']
69
+ oid = result['codeSystemOid'] || result['codeSystem']
70
+ return "<value xsi:type=\"CD\" code=\"#{result['code']}\" codeSystem=\"#{oid}\" codeSystemName=\"#{HQMF::Util::CodeSystemHelper.code_system_for(oid)}\"/>" if result['code']
72
71
  return "<value xsi:type=\"PQ\" value=\"#{result['value']}\" unit=\"#{result['unit']}\"/>" if result['unit']
73
72
  end
74
73
 
@@ -9,7 +9,7 @@ module QRDA
9
9
  patient.qdmPatient.birthDatetime = DateTime.parse(patient_element.at_xpath('cda:birthTime')['value'])
10
10
  pcbd = QDM::PatientCharacteristicBirthdate.new
11
11
  pcbd.birthDatetime = patient.qdmPatient.birthDatetime
12
- pcbd.dataElementCodes = [{ code: '21112-8', codeSystem: 'LOINC' }]
12
+ pcbd.dataElementCodes = [{ code: '21112-8', codeSystemOid: '2.16.840.1.113883.6.1' }]
13
13
  patient.qdmPatient.dataElements << pcbd
14
14
 
15
15
  pcs = QDM::PatientCharacteristicSex.new
@@ -29,9 +29,9 @@ module QRDA
29
29
  end
30
30
 
31
31
  def code_if_present(code_element)
32
- return unless code_element && code_element['codeSystem'] && code_element['code']
32
+ return unless code_element && code_element['code'] && code_element['codeSystem']
33
33
 
34
- QDM::Code.new(code_element['code'], HQMF::Util::CodeSystemHelper.code_system_for(code_element['codeSystem']))
34
+ QDM::Code.new(code_element['code'], code_element['codeSystem'])
35
35
  end
36
36
  end
37
37
  end
@@ -79,9 +79,8 @@ module QRDA
79
79
  end
80
80
 
81
81
  def code_if_present(code_element)
82
- return unless code_element && code_element['codeSystem'] && code_element['code']
83
-
84
- QDM::Code.new(code_element['code'], HQMF::Util::CodeSystemHelper.code_system_for(code_element['codeSystem']))
82
+ return unless code_element && code_element['code'] && code_element['codeSystem']
83
+ QDM::Code.new(code_element['code'], code_element['codeSystem'])
85
84
  end
86
85
 
87
86
  def extract_dates(parent_element, entry)
@@ -122,20 +121,21 @@ module QRDA
122
121
  # If a frequency interval is not found, return nil
123
122
  return nil unless frequency[:low]
124
123
  # If a frequency interval is found, search for a corresponding Direct Reference Code
125
- key, value = Qrda::Export::Helper::FrequencyHelper::FREQUENCY_CODE_MAP.select { |_k,v| v[:low] == frequency['low'] && v[:high] == frequency['high'] && v[:institution_specified] == frequency['institution_specified'] && v[:unit] == frequency['unit'] }.first
124
+ key, value = Qrda::Export::Helper::FrequencyHelper::FREQUENCY_CODE_MAP.select { |_k,v| v[:low] == frequency[:low] && v[:high] == frequency[:high] && v[:institution_specified] == frequency[:institution_specified] && v[:unit] == frequency[:unit] }.first
126
125
  # If a Direct Reference Code isn't found, return nil
127
126
  return nil unless key
128
127
  # If a Direct Reference Code is found, return that code
129
- QDM::Code.new(key, HQMF::Util::CodeSystemHelper.code_system_for(value[:codeSystem]))
128
+ oid = value[:codeSystem] || value[:codeSystemOid]
129
+ QDM::Code.new(key, oid)
130
130
  end
131
131
 
132
132
  def extract_frequency_in_hours(parent_element, frequency_xpath)
133
133
  # Need to go get low, high and institutionspecified
134
- low = parent_element.at_xpath("#{frequency_xpath}/@value").value if parent_element.at_xpath("#{frequency_xpath}/@value")
135
- low = parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:low/@value").value if parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:low/@value")
134
+ low = parent_element.at_xpath("#{frequency_xpath}/@value").value.to_i if parent_element.at_xpath("#{frequency_xpath}/@value")
135
+ low = parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:low/@value").value.to_i if parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:low/@value")
136
136
  unit = parent_element.at_xpath("#{frequency_xpath}/@unit").value if parent_element.at_xpath("#{frequency_xpath}/@unit")
137
137
  unit = parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:low/@unit").value if parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:low/@unit")
138
- high = parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:high/@value").value if parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:high/@value")
138
+ high = parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:high/@value").value.to_i if parent_element.at_xpath("#{frequency_xpath}/cda:period/cda:high/@value")
139
139
  institution_specified = parent_element.at_xpath("#{frequency_xpath}/@institutionSpecified") || false
140
140
  # Expected units are H (hours) and D (days)
141
141
  if unit && unit.upcase == 'D'
@@ -186,7 +186,7 @@ module QRDA
186
186
  code_elements = coded_parent_element.xpath(@code_xpath)
187
187
  code_elements.each do |code_element|
188
188
  if code_element['nullFlavor'] == 'NA' && code_element['sdtc:valueSet']
189
- entry.dataElementCodes = [{ code: code_element['sdtc:valueSet'], codeSystem: 'NA_VALUESET' }]
189
+ entry.dataElementCodes = [{ code: code_element['sdtc:valueSet'], codeSystemOid: '1.2.3.4.5.6.7.8.9.10' }]
190
190
  end
191
191
  end
192
192
  end
@@ -6,7 +6,6 @@ module HQMF
6
6
  '2.16.840.1.113883.6.1' => 'LOINC',
7
7
  '2.16.840.1.113883.6.96' => 'SNOMEDCT',
8
8
  '2.16.840.1.113883.6.12' => 'CPT',
9
- #'2.16.840.1.113883.3.88.12.80.32' => 'CPT', # Encounter Type from C32, a subset of CPT
10
9
  '2.16.840.1.113883.6.88' => 'RXNORM',
11
10
  '2.16.840.1.113883.6.103' => 'ICD9CM',
12
11
  '2.16.840.1.113883.6.104' => 'ICD9CM',
@@ -35,37 +34,17 @@ module HQMF
35
34
  '2.16.840.1.113883.3.221.5' => "Source of Payment Typology",
36
35
  '2.16.840.1.113883.6.13' => 'CDT',
37
36
  '2.16.840.1.113883.18.2' => 'AdministrativeSex',
38
- '2.16.840.1.113883.5.1' => 'AdministrativeGender'
39
- }
40
-
41
- CODE_SYSTEM_ALIASES = {
42
- 'FDA SPL' => 'NCI Thesaurus',
43
- 'HSLOC' => 'HL7 Healthcare Service Location',
44
- 'SOP' => "Source of Payment Typology"
45
- }
46
-
47
- # Some old OID are still around in data, this hash maps retired OID values to
48
- # the new value
49
- OID_ALIASES = {
50
- '2.16.840.1.113883.6.59' => '2.16.840.1.113883.12.292' # CVX
51
- }
37
+ '2.16.840.1.113883.5.1' => 'AdministrativeGender',
38
+ '1.2.3.4.5.6.7.8.9.10' => 'NA_VALUESET'
39
+ }.freeze
52
40
 
53
41
  # Returns the name of a code system given an oid
54
42
  # @param [String] oid of a code system
55
43
  # @return [String] the name of the code system as described in the measure definition JSON
56
44
  def self.code_system_for(oid)
57
- oid = OID_ALIASES[oid] if OID_ALIASES[oid]
58
45
  CODE_SYSTEMS[oid] || "Unknown"
59
46
  end
60
47
 
61
- # Returns the oid for a code system given a codesystem name
62
- # @param [String] the name of the code system
63
- # @return [String] the oid of the code system
64
- def self.oid_for_code_system(code_system)
65
- code_system = CODE_SYSTEM_ALIASES[code_system] if CODE_SYSTEM_ALIASES[code_system]
66
- CODE_SYSTEMS.invert[code_system]
67
- end
68
-
69
48
  # Returns the whole map of OIDs to code systems
70
49
  # @terurn [Hash] oids as keys, code system names as values
71
50
  def self.code_systems
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cqm-reports
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - The MITRE Corporation
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-22 00:00:00.000000000 Z
11
+ date: 2019-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cqm-models
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.1.1.0
19
+ version: 2.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.1.1.0
26
+ version: 2.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mustache
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -248,7 +248,10 @@ files:
248
248
  - lib/qrda-export/catIII-r2-1/qrda_header/_author.mustache
249
249
  - lib/qrda-export/catIII-r2-1/qrda_header/_custodian.mustache
250
250
  - lib/qrda-export/catIII-r2-1/qrda_header/_documentation_of_service_event.mustache
251
+ - lib/qrda-export/catIII-r2-1/qrda_header/_information_recipient.mustache
251
252
  - lib/qrda-export/catIII-r2-1/qrda_header/_legal_authenticator.mustache
253
+ - lib/qrda-export/catIII-r2-1/qrda_header/_participant_ehr.mustache
254
+ - lib/qrda-export/catIII-r2-1/qrda_header/_participant_location.mustache
252
255
  - lib/qrda-export/helper/aggregate_object_helper.rb
253
256
  - lib/qrda-export/helper/cat1_view_helper.rb
254
257
  - lib/qrda-export/helper/date_helper.rb
@@ -335,8 +338,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
335
338
  - !ruby/object:Gem::Version
336
339
  version: '0'
337
340
  requirements: []
338
- rubyforge_project:
339
- rubygems_version: 2.7.7
341
+ rubygems_version: 3.0.3
340
342
  signing_key:
341
343
  specification_version: 4
342
344
  summary: A library for import and export of reports for use with electronic Clinical