Class: CQM::Converter::QDMPatient

Inherits:
Object
  • Object
show all
Defined in:
lib/cqm/converter/qdm_patient.rb

Overview

CQM Converter class for QDM based patients.

Instance Method Summary collapse

Constructor Details

#initializeQDMPatient

Initialize a new QDMPatient converter. NOTE: This should be done once, and then used for every QDM Patient you want to convert, since it takes a few seconds to initialize the conversion environment.



8
9
10
11
# File 'lib/cqm/converter/qdm_patient.rb', line 8

def initialize
  @qdm_model_attrs = Utils.gather_qdm_model_attrs
  @qdm_to_hds_mappings = Utils.gather_qdm_to_hds_mappings(@qdm_model_attrs)
end

Instance Method Details

#to_hds(patient) ⇒ Object

Given a QDM patient, return a corresponding HDS record.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
118
119
120
121
122
123
124
125
126
# File 'lib/cqm/converter/qdm_patient.rb', line 14

def to_hds(patient)
  # Start with a new HDS record.
  record = Record.new

  # Loop over the QDM Patient's data elements, and create the corresponding
  # HDS Record Entry models on the newly created record.
  patient.dataElements.each do |data_element|
    category = data_element.category if data_element.fields.include? 'category'
    next unless category
    # Handle patient characteristics seperately.
    next if data_element.category == 'patient_characteristic'

    # Grab the QDM datatype name of this data element.
    qdm_model_name = data_element.class.name.demodulize

    # Handle mismatched HDS names for QDM things.
    category = Utils.qdm_to_hds_class_type(category)

    # Grab the corresponding HDS model we will cast this QDM model into.
    hds_model = category.camelize.constantize

    # Start with a new HDS entry.
    hds_entry = hds_model.new

    # Populate codes.
    hds_entry.codes = Utils.qdm_codes_to_hds_codes(data_element.dataElementCodes)

    # Populate OID.
    hds_entry.oid = data_element.hqmfOid

    # Populate description.
    hds_entry.description = data_element.description

    # Set type.
    hds_entry.set(_type: hds_model.to_s)

    # Set status_code.
    status = data_element.fields.include?('qdmStatus') ? data_element[:qdmStatus] : nil
    status = 'ordered' if status == 'order'
    hds_entry.status_code = { 'HL7 ActStatus': [status] }

    # Grab the QDM attribute mappings for this data element, and construct the
    # corresponding HDS attributes.
    hds_attrs = {}
    @qdm_to_hds_mappings[qdm_model_name].each do |qdm_attr, hds_attr|
      next if data_element[qdm_attr].nil?
      extracted_value = extractor(data_element[qdm_attr].as_json)
      if hds_attr.is_a?(Hash) && hds_attr[:low]
        # Handle something that has multiple parts.
        hds_attrs[hds_attr[:low]] = extracted_value.first
        hds_attrs[hds_attr[:high]] = extracted_value.last if hds_attr[:high]
      elsif extracted_value.is_a?(Array) && extracted_value.any? && extracted_value.first.is_a?(Hash) && extracted_value.first[:code] && hds_attr != 'facility' && hds_attr != 'components'
        # Handle a result that is returning multiple codes.
        hds_attrs[hds_attr] = [CodedResultValue.new(codes: Utils.qdm_codes_to_hds_codes(extracted_value), description: extracted_value.first[:title])]
      elsif extracted_value.is_a?(Array)
        # Handle simple Arrays.
        hds_attrs[hds_attr] = { values: extracted_value } if extracted_value.any?
      elsif hds_attr == 'values' && extracted_value.key?(:scalar)
        # Handle a Quantity.
        hds_attrs[hds_attr] = [PhysicalQuantityResultValue.new(extracted_value)]
      elsif hds_attr == 'values' && extracted_value.key?(:code)
        # Handle a Code result.
        hds_attrs[hds_attr] = [CodedResultValue.new(codes: Utils.qdm_codes_to_hds_codes([extracted_value]), description: extracted_value[:title])]
      elsif hds_attr == 'dose'
        # Handle a dosage.
        hds_attrs[hds_attr] = dose_extractor(extracted_value)
      else
        # Nothing special.
        hds_attrs[hds_attr] = extracted_value
      end
    end

    # If there is an actual negationReason, set negationInd to true.
    if hds_attrs.key?('negationReason') && !hds_attrs['negationReason'].nil?
      hds_attrs['negationInd'] = true
    end

    # Unpack references.
    unpack_references(hds_attrs)

    # Unpack facility.
    unpack_facility(hds_attrs)

    # Unpack diagnosis.
    unpack_diagnosis(hds_attrs)

    # Unpack components.
    unpack_components(hds_attrs)

    # Communication entries need direction, which we can get from the QDM model name.
    if hds_entry._type == 'Communication'
      hds_attrs['direction'] = qdm_model_name.underscore
    end

    # Ignore infinity dates.
    Utils.fix_infinity_dates(hds_attrs)

    # Apply the attributes to the entry.
    hds_entry.set(hds_attrs)

    # Add entry to HDS record, make sure to handle tricky plural types.
    plural_category = ['medical_equipment'].include?(category) ? category : category.pluralize
    record.send(plural_category) << hds_entry unless hds_entry.codes.empty?
  end

  # Unpack patient characteristics.
  unpack_patient_characteristics(patient, record)

  # Unpack extended_data.
  unpack_extended_data(patient, record)

  record
end