class HQMF2::FieldValueHelper

Generates field values based on understanding of the HQMF 2.1 spec

Public Class Methods

any_flavor(element) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 99
def self.any_flavor(element)
  element && (element['flavorId'] == 'ANY.NONNULL' ||
              element.at_xpath('@xsi:type', HQMF2::Document::NAMESPACES) == 'ANY')
end
check_and_set_if_any(element, field, fields) click to toggle source

Use when checking if the element is a “ANY” type, sets the field key if it is

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 93
def self.check_and_set_if_any(element, field, fields)
  any = any_flavor(element)
  fields[field] = AnyValue.new if any
  any
end
extract_template_ids(entry) click to toggle source

Extract template ids from the given entry

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 168
def self.extract_template_ids(entry)
  entry.xpath('./cda:templateId/cda:item', HQMF2::Document::NAMESPACES).collect do |template_def|
    HQMF2::Utilities.attr_val(template_def, '@root')
  end
end
handle_fields_per_criteria(criteria, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 24
def self.handle_fields_per_criteria(criteria, fields)
  case criteria.name
  when 'encounterCriteria'
    parse_encounter_fields(criteria, fields)
  when 'actCriteria'
    parse_act_criteria_fields(criteria, fields)
  when 'observationCriteria'
    parse_observation_fields(criteria, fields)
  when 'procedureCriteria'
    parse_procedure_fields(criteria, fields)
  when 'supplyCriteria'
    parse_supply_fields(criteria, fields)
  when 'substanceAdministrationCriteria'
    parse_substance_administration_fields(criteria, fields)
  when 'grouperCriteria'
    parse_grouper_fields(criteria, fields)
  end
end
handle_loc(entry, fields) click to toggle source

If type code for this field value is LOC, handle specifics

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 152
def self.handle_loc(entry, fields)
  loc = entry.at_xpath("./cda:participation[@typeCode='LOC']/cda:role[@classCode='SDLOC']",
                       HQMF2::Document::NAMESPACES)
  return unless loc
  # does it have an effective time?
  low = loc.at_xpath('./cda:effectiveTime/cda:low/..')
  high = loc.at_xpath('./cda:effectiveTime/cda:high/..')
  code = loc.at_xpath('./cda:code')
  # looking at the 2.4.0 measure bundle these values are set to null if they exist
  # so that is what I am doing for now
  fields['FACILITY_LOCATION_ARRIVAL_DATETIME'] = AnyValue.new if low
  fields['FACILITY_LOCATION_DEPARTURE_DATETIME'] = AnyValue.new if high
  fields['FACILITY_LOCATION'] = Coded.new(code) if code
end
high_field_name(template_ids) click to toggle source

Returns the proper name for the high field given the list of template ids

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 140
def self.high_field_name(template_ids)
  if template_ids.include?('2.16.840.1.113883.10.20.28.3.13')
    'REMOVAL_DATETIME'
  elsif template_ids.include?('2.16.840.1.113883.10.20.28.3.110') ||
        template_ids.include?('2.16.840.1.113883.10.20.28.3.116')
    'ABATEMENT_DATETIME'
  else
    'DISCHARGE_DATETIME'
  end
end
low_field_name(template_ids) click to toggle source

Returns the proper name for the low field given the list of template ids

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 128
def self.low_field_name(template_ids)
  if template_ids.include?('2.16.840.1.113883.10.20.28.3.51')
    'ACTIVE_DATETIME'
  elsif template_ids.include?('2.16.840.1.113883.10.20.28.3.110') ||
        template_ids.include?('2.16.840.1.113883.10.20.28.3.116')
    'ONSET_DATETIME'
  else
    'ADMISSION_DATETIME'
  end
end
parse_act_criteria_fields(_entry, _fields) click to toggle source

The “parse_”s after this point handle extraction of data criteria based on field names

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 176
def self.parse_act_criteria_fields(_entry, _fields)
end
parse_any(element, field, fields) click to toggle source

handle any value

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 87
def self.parse_any(element, field, fields)
  any = check_and_set_if_any(element, field, fields)
  fields[field] = DateCriteria.parse_value(element) if element && !any
end
parse_cd(element, field, fields) click to toggle source

The next group of “parse_” methods also first check if the value is of the “ANY” type, and only parse if it isn't

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 56
def self.parse_cd(element, field, fields)
  any = check_and_set_if_any(element, field, fields)
  fields[field] = Coded.new(element) if element && !any
end
parse_cs(element, field, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 71
def self.parse_cs(element, field, fields)
  # Only possible result is AnyValue
  check_and_set_if_any(element, field, fields)
end
parse_date_fields(entry, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 104
def self.parse_date_fields(entry, fields)
  # handle embded date fields
  times = [{ key: 'signeddatetime', field: 'SIGNED_DATETIME', highlow: 'high' },
           { key: 'startdatetime', field:  'START_DATETIME', highlow: 'low' },
           { key: 'stopdatetime', field:  'STOP_DATETIME', highlow: 'high' },
           { key: 'recordeddatetime', field: 'RECORDED_DATETIME', highlow: 'high' }
          ]
  times.each do |e|
    date = entry.at_xpath("cda:participation[@typeCode='AUT']/cda:role/cda:id/cda:item[@extension = '#{e[:key]}']/../../../cda:time")
    fields[e[:field]] = Range.new(date, 'IVL_PQ') if date
  end

  # Special case handle effectiveTime element , by default low is start datetime
  # and high is stop datetime.  This changes for certain elements
  template_ids = extract_template_ids(entry)
  low = entry.at_xpath('./cda:effectiveTime/cda:low/..')
  high = entry.at_xpath('./cda:effectiveTime/cda:high/..')

  fields[low_field_name(template_ids)] = Range.new(low, 'IVL_PQ') if low

  fields[high_field_name(template_ids)] = Range.new(high, 'IVL_PQ') if high
end
parse_dset_cd(element, field, fields) click to toggle source

The next group of “parse_” methods handle extracting values for different types of criteria

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 45
def self.parse_dset_cd(element, field, fields)
  if element
    item = element.at_xpath('./cda:item')
    any = any_flavor(item) || any_flavor(element)
    fields[field] = AnyValue.new if any
    fields[field] = Coded.new(item) if item && !any
  end
end
parse_encounter_fields(entry, fields) click to toggle source

Ignoring line limits here as it would be hard to create the deep xPaths with these limits. rubocop:disable Metrics/LineLength

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 207
def self.parse_encounter_fields(entry, fields)
  # Added a check for Principal Diagnosis and Diagnosis. QDM 4.2 Update
  principal = entry.at_xpath("./cda:outboundRelationship[@typeCode='REFR']/cda:actCriteria/cda:code[@code='52534-5']",
                             HQMF2::Document::NAMESPACES)
  if principal
    parse_cd(
      entry.at_xpath(
        "./cda:outboundRelationship[@typeCode='REFR']/cda:actCriteria/cda:outboundRelationship[@typeCode='SUBJ']/cda:observationCriteria/cda:value",
        HQMF2::Document::NAMESPACES
      ), 'PRINCIPAL_DIAGNOSIS', fields)
  end

  diagnosis = entry.at_xpath("./cda:outboundRelationship[@typeCode='REFR']/cda:actCriteria/cda:code[@code='29308-4']",
                             HQMF2::Document::NAMESPACES)
  if diagnosis
    parse_cd(
      entry.at_xpath(
        "./cda:outboundRelationship[@typeCode='REFR']/cda:actCriteria/cda:outboundRelationship[@typeCode='SUBJ']/cda:observationCriteria/cda:value",
        HQMF2::Document::NAMESPACES
      ), 'DIAGNOSIS', fields)
  end

  parse_pq(entry.at_xpath('./cda:lengthOfStayQuantity', HQMF2::Document::NAMESPACES), 'LENGTH_OF_STAY', fields)
  parse_cd(entry.at_xpath('./cda:dischargeDispositionCode', HQMF2::Document::NAMESPACES), 'DISCHARGE_STATUS', fields)

  handle_loc(entry, fields)
end
parse_field_values(entry) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 4
def self.parse_field_values(entry)
  return if entry.nil?
  criteria = entry.at_xpath('./cda:actCriteria | ./cda:observationCriteria | ./cda:encounterCriteria |
                             ./cda:procedureCriteria | ./cda:supplyCriteria |
                             ./cda:substanceAdministrationCriteria | ./cda:grouperCriteria')

  return {} if criteria.nil?
  fields = {}
  # Negation is handled in the data criteria parsing class and not as a field value.
  # Not using the reasonCode element because the QDM HQMF ig states that reason is in an outbound relationship.
  # parse_dset_cd(criteria.at_xpath('./cda:reasonCode', HQMF2::Document::NAMESPACES), 'REASON', fields) unless
  # negated.
  parse_dset_cd(criteria.at_xpath('./cda:priorityCode', HQMF2::Document::NAMESPACES), 'ORDINAL', fields)
  parse_date_fields(criteria, fields)

  handle_fields_per_criteria(criteria, fields)

  fields
end
parse_grouper_fields(_entry, _fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 248
def self.parse_grouper_fields(_entry, _fields)
end
parse_ivl_int(element, field, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 66
def self.parse_ivl_int(element, field, fields)
  any = check_and_set_if_any(element, field, fields)
  fields[field] = Range.new(element) if element && !any
end
parse_observation_fields(entry, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 190
def self.parse_observation_fields(entry, fields)
  parse_dset_cd(entry.at_xpath('./cda:methodCode', HQMF2::Document::NAMESPACES), 'METHOD', fields)
  parse_dset_cd(entry.at_xpath('./cda:targetSiteCode', HQMF2::Document::NAMESPACES),
                'ANATOMICAL_LOCATION_SITE', fields)
  parse_cd(entry.at_xpath("./cda:participation[@typeCode='SBJ']/cda:role[@classCode='PRS']/cda:code",
                          HQMF2::Document::NAMESPACES),
           'RELATIONSHIP', fields)
  parse_pq(entry.at_xpath("./cda:outboundRelationship[@typeCode='REFV']/cda:observationCriteria/cda:value/cda:high",
                          HQMF2::Document::NAMESPACES),
           'REFERENCE_RANGE_HIGH', fields)
  parse_pq(entry.at_xpath("./cda:outboundRelationship[@typeCode='REFV']/cda:observationCriteria/cda:value/cda:low",
                          HQMF2::Document::NAMESPACES),
           'REFERENCE_RANGE_LOW', fields)
end
parse_pq(element, field, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 76
def self.parse_pq(element, field, fields)
  any = check_and_set_if_any(element, field, fields)
  fields[field] = Range.new(element) if element && !any
end
parse_procedure_fields(entry, fields) click to toggle source

rubocop:enable Metrics/LineLength

# File lib/hqmf-parser/2.0/field_value_helper.rb, line 237
def self.parse_procedure_fields(entry, fields)
  parse_dset_cd(entry.at_xpath('./cda:methodCode', HQMF2::Document::NAMESPACES), 'METHOD', fields)
  parse_dset_cd(entry.at_xpath('./cda:approachSiteCode', HQMF2::Document::NAMESPACES),
                'ANATOMICAL_APPROACH_SITE', fields)
  parse_dset_cd(entry.at_xpath('./cda:targetSiteCode', HQMF2::Document::NAMESPACES),
                'ANATOMICAL_LOCATION_SITE', fields)
end
parse_substance_administration_fields(entry, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 179
def self.parse_substance_administration_fields(entry, fields)
  parse_dset_cd(entry.at_xpath('./cda:methodCode', HQMF2::Document::NAMESPACES), 'METHOD', fields)
  parse_dset_cd(entry.at_xpath('./cda:approachSiteCode', HQMF2::Document::NAMESPACES),
                'ANATOMICAL_APPROACH_SITE', fields)
  parse_dset_cd(entry.at_xpath('./cda:targetSiteCode', HQMF2::Document::NAMESPACES),
                'ANATOMICAL_LOCATION_SITE', fields)
  parse_cd(entry.at_xpath('./cda:routeCode', HQMF2::Document::NAMESPACES), 'ROUTE', fields)
  parse_pq(entry.at_xpath('./cda:doseQuantity', HQMF2::Document::NAMESPACES), 'DOSE', fields)
  parse_pq(entry.at_xpath('./cda:repeatNumber', HQMF2::Document::NAMESPACES), 'REFILLS', fields)
end
parse_supply_fields(_entry, _fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 245
def self.parse_supply_fields(_entry, _fields)
end
parse_ts(element, field, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 61
def self.parse_ts(element, field, fields)
  any = check_and_set_if_any(element, field, fields)
  fields[field] = Value.new(element) if element && !any
end
parse_value(element, field, fields) click to toggle source
# File lib/hqmf-parser/2.0/field_value_helper.rb, line 81
def self.parse_value(element, field, fields)
  any = check_and_set_if_any(element, field, fields)
  fields[field] = DateCriteria.parse_value(element) if element && !any
end