Class: DaVinciPlanNetTestKit::Generator::MustSupportMetadataExtractor
- Inherits:
-
Object
- Object
- DaVinciPlanNetTestKit::Generator::MustSupportMetadataExtractor
- Defined in:
- lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb
Instance Attribute Summary collapse
-
#ig_resources ⇒ Object
Returns the value of attribute ig_resources.
-
#profile ⇒ Object
Returns the value of attribute profile.
-
#profile_elements ⇒ Object
Returns the value of attribute profile_elements.
-
#resource ⇒ Object
Returns the value of attribute resource.
Instance Method Summary collapse
- #all_must_support_elements ⇒ Object
- #discriminators(slice) ⇒ Object
- #get_type_must_support_metadata(current_metadata, current_element) ⇒ Object
- #handle_choice_type_in_sliced_element(current_metadata, must_support_elements_metadata) ⇒ Object
- #handle_fixed_values(metadata, element) ⇒ Object
-
#handle_special_cases ⇒ Object
SPECIAL CASE ####.
- #handle_type_must_support_target_profiles(type, metadata) ⇒ Object
-
#initialize(profile_elements, profile, resource, ig_resources) ⇒ MustSupportMetadataExtractor
constructor
A new instance of MustSupportMetadataExtractor.
- #is_uscdi_requirement_element?(element) ⇒ Boolean
- #must_support_elements ⇒ Object
- #must_support_extension_elements ⇒ Object
- #must_support_extensions ⇒ Object
- #must_support_pattern_slice_elements ⇒ Object
- #must_support_slice_elements ⇒ Object
- #must_support_slices ⇒ Object
- #must_support_type_slice_elements ⇒ Object
- #must_support_value_slice_elements ⇒ Object
- #must_supports ⇒ Object
- #pattern_slices ⇒ Object
- #plain_must_support_elements ⇒ Object
-
#remove_observation_data_absent_reason ⇒ Object
ONC and US Core 4.0.0 both clarified that health IT developers that always provide HL7 FHIR “observation” values are not required to demonstrate Health IT Module support for “dataAbsentReason” elements.
- #save_type_code?(type) ⇒ Boolean
- #sliced_element(slice) ⇒ Object
- #type_must_support_extension?(extensions) ⇒ Boolean
- #type_slices ⇒ Object
- #value_slices ⇒ Object
Constructor Details
#initialize(profile_elements, profile, resource, ig_resources) ⇒ MustSupportMetadataExtractor
Returns a new instance of MustSupportMetadataExtractor.
10 11 12 13 14 15 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 10 def initialize(profile_elements, profile, resource, ig_resources) self.profile_elements = profile_elements self.profile = profile self.resource = resource self.ig_resources = ig_resources end |
Instance Attribute Details
#ig_resources ⇒ Object
Returns the value of attribute ig_resources.
8 9 10 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 8 def ig_resources @ig_resources end |
#profile ⇒ Object
Returns the value of attribute profile.
8 9 10 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 8 def profile @profile end |
#profile_elements ⇒ Object
Returns the value of attribute profile_elements.
8 9 10 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 8 def profile_elements @profile_elements end |
#resource ⇒ Object
Returns the value of attribute resource.
8 9 10 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 8 def resource @resource end |
Instance Method Details
#all_must_support_elements ⇒ Object
36 37 38 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 36 def all_must_support_elements profile_elements.select { |element| element.mustSupport || is_uscdi_requirement_element?(element) } end |
#discriminators(slice) ⇒ Object
65 66 67 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 65 def discriminators(slice) slice.slicing.discriminator end |
#get_type_must_support_metadata(current_metadata, current_element) ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 238 def (, current_element) current_element.type.map do |type| if type_must_support_extension?(type.extension) = { path: "#{[:path].delete_suffix('[x]')}#{type.code.upcase_first}", original_path: [:path] } [:types] = [type.code] if save_type_code?(type) handle_type_must_support_target_profiles(type, ) if type.code == 'Reference' end end.compact end |
#handle_choice_type_in_sliced_element(current_metadata, must_support_elements_metadata) ⇒ Object
269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 269 def handle_choice_type_in_sliced_element(, ) = .find do || [:original_path].present? && [:path].include?( [:original_path] ) end if .present? [:original_path] = [:path] [:path] = [:path].sub([:original_path], [:path]) end end |
#handle_fixed_values(metadata, element) ⇒ Object
213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 213 def handle_fixed_values(, element) if element.fixedUri.present? [:fixed_value] = element.fixedUri elsif element.patternCodeableConcept.present? [:fixed_value] = element.patternCodeableConcept.coding.first.code [:path] += '.coding.code' elsif element.fixedCode.present? [:fixed_value] = element.fixedCode elsif element.patternIdentifier.present? [:fixed_value] = element.patternIdentifier.system [:path] += '.system' end end |
#handle_special_cases ⇒ Object
SPECIAL CASE ####
316 317 318 319 320 321 322 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 316 def handle_special_cases case profile.version when '1.1.0' MustSupportMetadataExtractorUsCore3.new(profile, @must_supports).handle_special_cases end end |
#handle_type_must_support_target_profiles(type, metadata) ⇒ Object
254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 254 def handle_type_must_support_target_profiles(type, ) index = 0 target_profiles = [] type.source_hash['_targetProfile']&.each do |hash| if hash.present? element = FHIR::Element.new(hash) target_profiles << type.targetProfile[index] if type_must_support_extension?(element.extension) end index += 1 end [:target_profiles] = target_profiles if target_profiles.present? end |
#is_uscdi_requirement_element?(element) ⇒ Boolean
29 30 31 32 33 34 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 29 def is_uscdi_requirement_element?(element) element.extension.any? do |extension| extension.url == 'http://hl7.org/fhir/us/core/StructureDefinition/uscdi-requirement' && extension.valueBoolean end && !element.mustSupport end |
#must_support_elements ⇒ Object
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 281 def must_support_elements plain_must_support_elements.each_with_object([]) do |current_element, | { path: current_element.path.gsub("#{resource}.", '') }.tap do || if is_uscdi_requirement_element?(current_element) [:uscdi_only] = true end = (, current_element) if .any? .concat() else handle_choice_type_in_sliced_element(, ) supported_types = current_element.type.select { |type| save_type_code?(type) }.map { |type| type.code } [:types] = supported_types if supported_types.present? handle_type_must_support_target_profiles(current_element.type.first, ) if current_element.type.first&.code == 'Reference' handle_fixed_values(, current_element) .delete_if do || [:path] == [:path] && [:fixed_value].blank? end << end end end.uniq end |
#must_support_extension_elements ⇒ Object
40 41 42 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 40 def must_support_extension_elements all_must_support_elements.select { |element| element.path.end_with? 'extension' } end |
#must_support_extensions ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 44 def must_support_extensions must_support_extension_elements.map do |element| { id: element.id, url: element.type.first.profile.first }.tap do || if is_uscdi_requirement_element?(element) [:uscdi_only] = true end end end end |
#must_support_pattern_slice_elements ⇒ Object
69 70 71 72 73 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 69 def must_support_pattern_slice_elements must_support_slice_elements.select do |element| discriminators(sliced_element(element)).first.type == 'pattern' end end |
#must_support_slice_elements ⇒ Object
57 58 59 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 57 def must_support_slice_elements all_must_support_elements.select { |element| !element.path.end_with?('extension') && element.sliceName.present? } end |
#must_support_slices ⇒ Object
205 206 207 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 205 def must_support_slices pattern_slices + type_slices + value_slices end |
#must_support_type_slice_elements ⇒ Object
136 137 138 139 140 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 136 def must_support_type_slice_elements must_support_slice_elements.select do |element| discriminators(sliced_element(element)).first.type == 'type' end end |
#must_support_value_slice_elements ⇒ Object
171 172 173 174 175 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 171 def must_support_value_slice_elements must_support_slice_elements.select do |element| discriminators(sliced_element(element)).first.type == 'value' end end |
#must_supports ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 17 def must_supports @must_supports = { extensions: must_support_extensions, slices: must_support_slices, elements: must_support_elements } handle_special_cases @must_supports end |
#pattern_slices ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 75 def pattern_slices must_support_pattern_slice_elements.map do |current_element| { name: current_element.id, path: current_element.path.gsub("#{resource}.", '') }.tap do || discriminator = discriminators(sliced_element(current_element)).first discriminator_path = discriminator.path discriminator_path = '' if discriminator_path == '$this' pattern_element = if discriminator_path.present? profile_elements.find { |element| element.id == "#{current_element.id}.#{discriminator_path}" } else current_element end [:discriminator] = if pattern_element.patternCodeableConcept.present? { type: 'patternCodeableConcept', path: discriminator_path, code: pattern_element.patternCodeableConcept.coding.first.code, system: pattern_element.patternCodeableConcept.coding.first.system } elsif pattern_element.patternCoding.present? { type: 'patternCoding', path: discriminator_path, code: pattern_element.patternCoding.code, system: pattern_element.patternCoding.system } elsif pattern_element.patternIdentifier.present? { type: 'patternIdentifier', path: discriminator_path, system: pattern_element.patternIdentifier.system } elsif pattern_element.binding&.strength == 'required' && pattern_element.binding&.valueSet.present? value_extractor = ValueExactor.new(ig_resources, resource, profile_elements) values = value_extractor.values_from_value_set_binding(pattern_element).presence || value_extractor.([[:path]]).presence || [] { type: 'requiredBinding', path: discriminator_path, values: values } else raise StandardError, 'Unsupported discriminator pattern type' end if is_uscdi_requirement_element?(current_element) [:uscdi_only] = true end end end end |
#plain_must_support_elements ⇒ Object
209 210 211 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 209 def plain_must_support_elements all_must_support_elements - must_support_extension_elements - must_support_slice_elements end |
#remove_observation_data_absent_reason ⇒ Object
ONC and US Core 4.0.0 both clarified that health IT developers that always provide HL7 FHIR “observation” values are not required to demonstrate Health IT Module support for “dataAbsentReason” elements. Remove MS check for dataAbsentReason and component.dataAbsentReason from vital sign profiles and observation lab profile Smoking status profile does not have MS on dataAbsentReason. It is safe to use profile.type == ‘Observation’
328 329 330 331 332 333 334 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 328 def remove_observation_data_absent_reason if profile.type == 'Observation' @must_supports[:elements].delete_if do |element| ['dataAbsentReason', 'component.dataAbsentReason'].include?(element[:path]) end end end |
#save_type_code?(type) ⇒ Boolean
234 235 236 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 234 def save_type_code?(type) 'Reference' == type.code end |
#sliced_element(slice) ⇒ Object
61 62 63 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 61 def sliced_element(slice) profile_elements.find { |element| element.id == slice.path || element.id == slice.id.sub(":#{slice.sliceName}", '') } end |
#type_must_support_extension?(extensions) ⇒ Boolean
227 228 229 230 231 232 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 227 def type_must_support_extension?(extensions) extensions&.any? do |extension| extension.url == 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support' && extension.valueBoolean end end |
#type_slices ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 142 def type_slices must_support_type_slice_elements.map do |current_element| discriminator = discriminators(sliced_element(current_element)).first type_path = discriminator.path type_path = '' if type_path == '$this' type_element = if type_path.present? elements.find { |element| element.id == "#{current_element.id}.#{type_path}" } else current_element end type_code = type_element.type.first.code { name: current_element.id, path: current_element.path.gsub("#{resource}.", ''), discriminator: { type: 'type', code: type_code.upcase_first } }.tap do || if is_uscdi_requirement_element?(current_element) [:uscdi_only] = true end end end end |
#value_slices ⇒ Object
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/davinci_plan_net_test_kit/generator/must_support_metadata_extractor.rb', line 177 def value_slices must_support_value_slice_elements.map do |current_element| { name: current_element.id, path: current_element.path.gsub("#{resource}.", ''), discriminator: { type: 'value' } }.tap do || [:discriminator][:values] = discriminators(sliced_element(current_element)).map do |discriminator| fixed_element = profile_elements.find do |element| element.id.starts_with?(current_element.id) && element.path == "#{current_element.path}.#{discriminator.path}" end { path: discriminator.path, value: fixed_element.fixedUri || fixed_element.fixedCode } end if is_uscdi_requirement_element?(current_element) [:uscdi_only] = true end end end end |