Class: IpaTestKit::Generator::MustSupportMetadataExtractor
- Inherits:
-
Object
- Object
- IpaTestKit::Generator::MustSupportMetadataExtractor
- Defined in:
- lib/ipa_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
- #add_device_distinct_identifier ⇒ Object
- #add_document_reference_category_values ⇒ Object
- #add_must_support_choices ⇒ Object
- #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_blood_pressure? ⇒ Boolean
- #is_vital_sign? ⇒ 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_blood_pressure_value ⇒ Object
Exclude Observation.value from observation-bp.
- #remove_device_carrier ⇒ Object
- #remove_document_reference_attachment_data_url ⇒ Object
-
#remove_document_reference_custodian ⇒ Object
US Core clarified that server implmentation is not required to support DocumentReference.custodian (FHIR-28393).
-
#remove_survey_questionnaire_response ⇒ Object
FHIR-37794 Server systems are not required to support US Core QuestionnaireResponse.
-
#remove_vital_sign_component ⇒ Object
Exclude Observation.component from vital sign profiles except observation-bp and observation-pulse-ox.
- #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.
8 9 10 11 12 13 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 8 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.
6 7 8 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 6 def ig_resources @ig_resources end |
#profile ⇒ Object
Returns the value of attribute profile.
6 7 8 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 6 def profile @profile end |
#profile_elements ⇒ Object
Returns the value of attribute profile_elements.
6 7 8 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 6 def profile_elements @profile_elements end |
#resource ⇒ Object
Returns the value of attribute resource.
6 7 8 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 6 def resource @resource end |
Instance Method Details
#add_device_distinct_identifier ⇒ Object
401 402 403 404 405 406 407 408 409 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 401 def add_device_distinct_identifier if profile.type == 'Device' # FHIR-36303 US Core 4.0.0 mistakenly removed MS from Device.distinctIdentifier # This will be fixed in US Core 5.0.0 @must_supports[:elements] << { path: 'distinctIdentifier' } end end |
#add_document_reference_category_values ⇒ Object
411 412 413 414 415 416 417 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 411 def add_document_reference_category_values return unless profile.type == 'DocumentReference' slice = @must_supports[:slices].find{|slice| slice[:path] == 'category'} slice[:discriminator][:values] = ['clinical-note'] if slice.present? end |
#add_must_support_choices ⇒ Object
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 360 def add_must_support_choices choices = [] choices << { paths: ['content.attachment.data', 'content.attachment.url'] } if profile.type == 'DocumentReference' case profile.version when '3.1.1' choices << { paths: ['udiCarrier.carrierAIDC', 'udiCarrier.carrierHRF'] } if profile.type == 'Device' when '4.0.0' case profile.type when 'Encounter' choices << { paths: ['reasonCode', 'reasonReference'] } choices << { paths: ['location.location', 'serviceProvider'] } when 'MedicationRequest' choices << { paths: ['reportedBoolean', 'reportedReference'] } end when '5.0.1' case profile.type when 'CareTeam' choices << { target_profiles: [ 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitionerrole' ] } when 'Condition' choices << { paths: ['onsetDateTime'], extension_ids: ['Condition.extension:assertedDate'] } when 'Encounter' choices << { paths: ['reasonCode', 'reasonReference'] } choices << { paths: ['location.location', 'serviceProvider'] } when 'MedicationRequest' choices << { paths: ['reportedBoolean', 'reportedReference'] } end end @must_supports[:choices] = choices if choices.present? end |
#all_must_support_elements ⇒ Object
27 28 29 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 27 def all_must_support_elements profile_elements.select { |element| element.mustSupport } end |
#discriminators(slice) ⇒ Object
52 53 54 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 52 def discriminators(slice) slice.slicing.discriminator end |
#get_type_must_support_metadata(current_metadata, current_element) ⇒ Object
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 213 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] } [:type] = [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
244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 244 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
188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 188 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 ####
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 287 def handle_special_cases remove_vital_sign_component remove_blood_pressure_value add_must_support_choices case profile.version when '3.1.1' remove_document_reference_custodian when '4.0.0' add_device_distinct_identifier when '5.0.1' add_document_reference_category_values remove_survey_questionnaire_response end end |
#handle_type_must_support_target_profiles(type, metadata) ⇒ Object
229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 229 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_blood_pressure? ⇒ Boolean
310 311 312 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 310 def is_blood_pressure? ['observation-bp', 'IpaBloodPressureProfile'].include?(profile.name) end |
#is_vital_sign? ⇒ Boolean
303 304 305 306 307 308 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 303 def is_vital_sign? [ 'http://hl7.org/fhir/StructureDefinition/vitalsigns', 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-vital-signs' ].include?(profile.baseDefinition) end |
#must_support_elements ⇒ Object
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 256 def must_support_elements plain_must_support_elements.each_with_object([]) do |current_element, | { path: current_element.path.gsub("#{resource}.", '') }.tap do || = (, 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
31 32 33 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 31 def must_support_extension_elements all_must_support_elements.select { |element| element.path.end_with? 'extension' } end |
#must_support_extensions ⇒ Object
35 36 37 38 39 40 41 42 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 35 def must_support_extensions must_support_extension_elements.map do |element| { id: element.id, url: element.type.first.profile.first } end end |
#must_support_pattern_slice_elements ⇒ Object
56 57 58 59 60 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 56 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
44 45 46 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 44 def must_support_slice_elements all_must_support_elements.select { |element| !element.path.end_with?('extension') && element.sliceName.present? } end |
#must_support_slices ⇒ Object
180 181 182 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 180 def must_support_slices pattern_slices + type_slices + value_slices end |
#must_support_type_slice_elements ⇒ Object
119 120 121 122 123 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 119 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
150 151 152 153 154 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 150 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
15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 15 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
62 63 64 65 66 67 68 69 70 71 72 73 74 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 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 62 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 end end end |
#plain_must_support_elements ⇒ Object
184 185 186 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 184 def plain_must_support_elements all_must_support_elements - must_support_extension_elements - must_support_slice_elements end |
#remove_blood_pressure_value ⇒ Object
Exclude Observation.value from observation-bp
324 325 326 327 328 329 330 331 332 333 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 324 def remove_blood_pressure_value if is_blood_pressure? @must_supports[:elements].delete_if do |element| element[:path].start_with?('value[x]') || element[:original_path]&.start_with?('value[x]') end @must_supports[:slices].delete_if do |slice| slice[:path].start_with?('value[x]') end end end |
#remove_device_carrier ⇒ Object
335 336 337 338 339 340 341 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 335 def remove_device_carrier if profile.type == 'Device' @must_supports[:elements].delete_if do |element| ['udiCarrier.carrierAIDC', 'udiCarrier.carrierHRF'].include?(element[:path]) end end end |
#remove_document_reference_attachment_data_url ⇒ Object
352 353 354 355 356 357 358 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 352 def if profile.type == 'DocumentReference' @must_supports[:elements].delete_if do |element| ['content.attachment.data', 'content.attachment.url'].include?(element[:path]) end end end |
#remove_document_reference_custodian ⇒ Object
US Core clarified that server implmentation is not required to support DocumentReference.custodian (FHIR-28393)
344 345 346 347 348 349 350 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 344 def remove_document_reference_custodian if profile.type == 'DocumentReference' @must_supports[:elements].delete_if do |element| element[:path] == 'custodian' end end end |
#remove_survey_questionnaire_response ⇒ Object
FHIR-37794 Server systems are not required to support US Core QuestionnaireResponse
420 421 422 423 424 425 426 427 428 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 420 def remove_survey_questionnaire_response return unless profile.type == 'Observation' && ['us-core-observation-survey', 'us-core-observation-sdoh-assessment'].include?(profile.id) element = @must_supports[:elements].find { |element| element[:path] == 'derivedFrom' } element[:target_profiles].delete_if do |url| url == 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-questionnaireresponse' end end |
#remove_vital_sign_component ⇒ Object
Exclude Observation.component from vital sign profiles except observation-bp and observation-pulse-ox
315 316 317 318 319 320 321 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 315 def remove_vital_sign_component if is_vital_sign? && !is_blood_pressure? && profile.name != 'IpaPulseOximetryProfile' @must_supports[:elements].delete_if do |element| element[:path].start_with?('component') end end end |
#save_type_code?(type) ⇒ Boolean
209 210 211 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 209 def save_type_code?(type) 'Reference' == type.code end |
#sliced_element(slice) ⇒ Object
48 49 50 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 48 def sliced_element(slice) profile_elements.find { |element| element.id == slice.path } end |
#type_must_support_extension?(extensions) ⇒ Boolean
202 203 204 205 206 207 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 202 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
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 125 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 } } end end |
#value_slices ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/ipa_test_kit/generator/must_support_metadata_extractor.rb', line 156 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 end end end |