cqm-reports 3.0.1 → 3.1.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 +4 -4
 - data/Gemfile +0 -1
 - data/README.md +1 -1
 - data/lib/cqm-reports.rb +0 -1
 - data/lib/html-export/qdm-patient/qdm_patient.mustache +5 -3
 - data/lib/html-export/qdm-patient/qdm_patient.rb +31 -1
 - data/lib/qrda-export/helper/patient_view_helper.rb +39 -0
 - data/lib/qrda-import/base-importers/section_importer.rb +30 -3
 - data/lib/qrda-import/patient_importer.rb +58 -60
 - metadata +16 -3
 - data/lib/qrda-import/entry_package.rb +0 -16
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: f221e687f62214c36812fd10c6f805bd4c8318d0
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 8ced778300575e57e368770bc705f8e5cc4f4d3d
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: d4056e6d8f4e26ad6247fa558511d5ce0aad9bc61ca0ecd7c31ec69f160b4c555ced11b5fdfc3ce0e518165de92b2efbd2538bde2d73128035a84e7fa06ddc8e
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 33d50e677dcb99de986b9d0a9e4423530fdbed178b99bb0a6512eedf41d4bcf0e8a0eeeb9a936a6035419914f0089fa7de8c1435bdd40971bdbc6861666bcd32
         
     | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -24,7 +24,7 @@ Importing QRDA 
     | 
|
| 
       24 
24 
     | 
    
         
             
            A QRDA document can be imported into a CQM::Patient (defined in [cqm-models](https://github.com/projecttacoma/cqm-models)) using the following commands.
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                    doc = Nokogiri::XML(file)
         
     | 
| 
       27 
     | 
    
         
            -
                    patient = QRDA::Cat1::PatientImporter.instance.parse_cat1(doc)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    patient, warnings = QRDA::Cat1::PatientImporter.instance.parse_cat1(doc)
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            Exporting QRDA Category I
         
     | 
| 
       30 
30 
     | 
    
         
             
            ==========
         
     | 
    
        data/lib/cqm-reports.rb
    CHANGED
    
    | 
         @@ -19,7 +19,6 @@ require_relative 'html-export/qdm-patient/qdm_patient.rb' 
     | 
|
| 
       19 
19 
     | 
    
         
             
            require_relative 'qrda-export/catI-r5/qrda1_r5.rb'
         
     | 
| 
       20 
20 
     | 
    
         
             
            require_relative 'qrda-export/catIII-r2-1/qrda3_r21.rb'
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
            require_relative 'qrda-import/entry_package.rb'
         
     | 
| 
       23 
22 
     | 
    
         
             
            require_relative 'qrda-import/cda_identifier.rb'
         
     | 
| 
       24 
23 
     | 
    
         
             
            require_relative 'qrda-import/narrative_reference_handler.rb'
         
     | 
| 
       25 
24 
     | 
    
         
             
            require_relative 'qrda-import/entry_finder.rb'
         
     | 
| 
         @@ -24,7 +24,7 @@ 
     | 
|
| 
       24 
24 
     | 
    
         
             
                      <div class="div-table-head patient_narr_th panel-heading"><span class="td_label">Date of birth</span></div>
         
     | 
| 
       25 
25 
     | 
    
         
             
                      <div class="div-table-head">{{{birthdate}}}</div>
         
     | 
| 
       26 
26 
     | 
    
         
             
                      <div class="div-table-head patient_narr_th panel-heading"><span class="td_label">Date of expiration</span></div>
         
     | 
| 
       27 
     | 
    
         
            -
                      <div class="div-table-head" 
     | 
| 
      
 27 
     | 
    
         
            +
                      <div class="div-table-head">{{{expiration}}}</div>
         
     | 
| 
       28 
28 
     | 
    
         
             
                    </div>
         
     | 
| 
       29 
29 
     | 
    
         
             
                    <div class="div-head-row patient_narr_tr panel panel-default patient-details">
         
     | 
| 
       30 
30 
     | 
    
         
             
                      <div class="div-table-head patient_narr_th panel-heading"><span class="td_label">Race</span></div>
         
     | 
| 
         @@ -39,8 +39,10 @@ 
     | 
|
| 
       39 
39 
     | 
    
         
             
                      <div class="div-table-head">{{{mrn}}} Cypress</div>
         
     | 
| 
       40 
40 
     | 
    
         
             
                    </div>
         
     | 
| 
       41 
41 
     | 
    
         
             
                    <div class="div-head-row patient_narr_tr panel panel-default patient-details">
         
     | 
| 
       42 
     | 
    
         
            -
                      <div class="div-table-head patient_narr_th panel-heading"><span class="td_label"> 
     | 
| 
       43 
     | 
    
         
            -
                      <div class="div-table-head" 
     | 
| 
      
 42 
     | 
    
         
            +
                      <div class="div-table-head patient_narr_th panel-heading"><span class="td_label">Address</span></div>
         
     | 
| 
      
 43 
     | 
    
         
            +
                      <div class="div-table-head">{{{patient_addresses}}}</div>
         
     | 
| 
      
 44 
     | 
    
         
            +
                      <div class="div-table-head patient_narr_th panel-heading"><span class="td_label">Telecom</span></div>
         
     | 
| 
      
 45 
     | 
    
         
            +
                      <div class="div-table-head">{{{patient_telecoms}}}</div>
         
     | 
| 
       44 
46 
     | 
    
         
             
                    </div>
         
     | 
| 
       45 
47 
     | 
    
         
             
                  </div>
         
     | 
| 
       46 
48 
     | 
    
         
             
                </div>
         
     | 
| 
         @@ -9,6 +9,36 @@ class QdmPatient < Mustache 
     | 
|
| 
       9 
9 
     | 
    
         
             
                @include_style = include_style
         
     | 
| 
       10 
10 
     | 
    
         
             
                @patient = patient
         
     | 
| 
       11 
11 
     | 
    
         
             
                @qdmPatient = patient.qdmPatient
         
     | 
| 
      
 12 
     | 
    
         
            +
                @patient_addresses = patient['addresses']
         
     | 
| 
      
 13 
     | 
    
         
            +
                @patient_telecoms = patient['telecoms']
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              def patient_addresses
         
     | 
| 
      
 17 
     | 
    
         
            +
                @patient_addresses ||= [CQM::Address.new(
         
     | 
| 
      
 18 
     | 
    
         
            +
                  use: 'HP',
         
     | 
| 
      
 19 
     | 
    
         
            +
                  street: ['202 Burlington Rd.'],
         
     | 
| 
      
 20 
     | 
    
         
            +
                  city: 'Bedford',
         
     | 
| 
      
 21 
     | 
    
         
            +
                  state: 'MA',
         
     | 
| 
      
 22 
     | 
    
         
            +
                  zip: '01730',
         
     | 
| 
      
 23 
     | 
    
         
            +
                  country: 'US'
         
     | 
| 
      
 24 
     | 
    
         
            +
                )]
         
     | 
| 
      
 25 
     | 
    
         
            +
                address_str = ""
         
     | 
| 
      
 26 
     | 
    
         
            +
                @patient_addresses.each do |address|
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # create formatted address
         
     | 
| 
      
 28 
     | 
    
         
            +
                  address_str += "<address>"
         
     | 
| 
      
 29 
     | 
    
         
            +
                  address['street'].each { |street| address_str += "#{street}<br>" }
         
     | 
| 
      
 30 
     | 
    
         
            +
                  address_str += "#{address['city']}, #{address['state']} #{address['zip']}<br> #{address['country']} </address>"
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
                address_str
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              def patient_telecoms
         
     | 
| 
      
 36 
     | 
    
         
            +
                @patient_telecoms ||= [CQM::Telecom.new(
         
     | 
| 
      
 37 
     | 
    
         
            +
                  use: 'HP',
         
     | 
| 
      
 38 
     | 
    
         
            +
                  value: '555-555-2003'
         
     | 
| 
      
 39 
     | 
    
         
            +
                )]
         
     | 
| 
      
 40 
     | 
    
         
            +
                # create formatted telecoms
         
     | 
| 
      
 41 
     | 
    
         
            +
                @patient_telecoms.map { |telecom| "(#{telecom['use']}) #{telecom['value']}" }.join("<br>")
         
     | 
| 
       12 
42 
     | 
    
         
             
              end
         
     | 
| 
       13 
43 
     | 
    
         | 
| 
       14 
44 
     | 
    
         
             
              def include_style?
         
     | 
| 
         @@ -25,7 +55,7 @@ class QdmPatient < Mustache 
     | 
|
| 
       25 
55 
     | 
    
         
             
              end
         
     | 
| 
       26 
56 
     | 
    
         | 
| 
       27 
57 
     | 
    
         
             
              def unit_string
         
     | 
| 
       28 
     | 
    
         
            -
                return "#{self['value']} "  
     | 
| 
      
 58 
     | 
    
         
            +
                return "#{self['value']} " if !self['unit'] || self['unit'] == '1'
         
     | 
| 
       29 
59 
     | 
    
         
             
                "#{self['value']} #{self['unit']}"
         
     | 
| 
       30 
60 
     | 
    
         
             
              end
         
     | 
| 
       31 
61 
     | 
    
         | 
| 
         @@ -16,16 +16,19 @@ module Qrda 
     | 
|
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                    def provider_npi
         
     | 
| 
       18 
18 
     | 
    
         
             
                      return nil unless self['ids']
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       19 
20 
     | 
    
         
             
                      self['ids'].map { |id| id if id['namingSystem'] == '2.16.840.1.113883.4.6' }.compact
         
     | 
| 
       20 
21 
     | 
    
         
             
                    end
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
                    def provider_tin
         
     | 
| 
       23 
24 
     | 
    
         
             
                      return nil unless self['ids']
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       24 
26 
     | 
    
         
             
                      self['ids'].map { |id| id if id['namingSystem'] == '2.16.840.1.113883.4.2' }.compact
         
     | 
| 
       25 
27 
     | 
    
         
             
                    end
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
       27 
29 
     | 
    
         
             
                    def provider_ccn
         
     | 
| 
       28 
30 
     | 
    
         
             
                      return nil unless self['ids']
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       29 
32 
     | 
    
         
             
                      self['ids'].map { |id| id if id['namingSystem'] == '2.16.840.1.113883.4.336' }.compact
         
     | 
| 
       30 
33 
     | 
    
         
             
                    end
         
     | 
| 
       31 
34 
     | 
    
         | 
| 
         @@ -40,6 +43,42 @@ module Qrda 
     | 
|
| 
       40 
43 
     | 
    
         
             
                    def given_name
         
     | 
| 
       41 
44 
     | 
    
         
             
                      self['givenNames'].join(' ')
         
     | 
| 
       42 
45 
     | 
    
         
             
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                    def gender
         
     | 
| 
      
 48 
     | 
    
         
            +
                      gender_elements = @qdmPatient.dataElements.select { |de| de._type == "QDM::PatientCharacteristicSex" }
         
     | 
| 
      
 49 
     | 
    
         
            +
                      return if gender_elements.empty?
         
     | 
| 
      
 50 
     | 
    
         
            +
                      gender_elements.first.dataElementCodes.first['code']
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    def birthdate
         
     | 
| 
      
 54 
     | 
    
         
            +
                      birthdate_elements = @qdmPatient.dataElements.select { |de| de._type == "QDM::PatientCharacteristicBirthdate" }
         
     | 
| 
      
 55 
     | 
    
         
            +
                      return "None" if birthdate_elements.empty?
         
     | 
| 
      
 56 
     | 
    
         
            +
                      birthdate_elements.first['birthDatetime']
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    def expiration
         
     | 
| 
      
 60 
     | 
    
         
            +
                      expired_elements = @qdmPatient.dataElements.select { |de| de._type == "QDM::PatientCharacteristicExpired" }
         
     | 
| 
      
 61 
     | 
    
         
            +
                      return "None" if expired_elements.empty?
         
     | 
| 
      
 62 
     | 
    
         
            +
                      expired_elements.first['expiredDatetime']
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    def race
         
     | 
| 
      
 66 
     | 
    
         
            +
                      race_elements = @qdmPatient.dataElements.select { |de| de._type == "QDM::PatientCharacteristicRace" }
         
     | 
| 
      
 67 
     | 
    
         
            +
                      return if race_elements.empty?
         
     | 
| 
      
 68 
     | 
    
         
            +
                      race_elements.first.dataElementCodes.first['code']
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    def ethnic_group
         
     | 
| 
      
 72 
     | 
    
         
            +
                      ethnic_elements = @qdmPatient.dataElements.select { |de| de._type == "QDM::PatientCharacteristicEthnicity" }
         
     | 
| 
      
 73 
     | 
    
         
            +
                      return if ethnic_elements.empty?
         
     | 
| 
      
 74 
     | 
    
         
            +
                      ethnic_elements.first.dataElementCodes.first['code']
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    def payer
         
     | 
| 
      
 78 
     | 
    
         
            +
                      payer_elements = @qdmPatient.dataElements.select { |de| de._type == "QDM::PatientCharacteristicPayer" }
         
     | 
| 
      
 79 
     | 
    
         
            +
                      return if payer_elements.empty?
         
     | 
| 
      
 80 
     | 
    
         
            +
                      payer_elements.first.dataElementCodes.first['code']
         
     | 
| 
      
 81 
     | 
    
         
            +
                    end
         
     | 
| 
       43 
82 
     | 
    
         
             
                  end
         
     | 
| 
       44 
83 
     | 
    
         
             
                end
         
     | 
| 
       45 
84 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module QRDA
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Cat1
         
     | 
| 
       3 
3 
     | 
    
         
             
                class SectionImporter
         
     | 
| 
       4 
     | 
    
         
            -
                  attr_accessor :check_for_usable, :status_xpath, :code_xpath
         
     | 
| 
      
 4 
     | 
    
         
            +
                  attr_accessor :check_for_usable, :status_xpath, :code_xpath, :warnings
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
                  def initialize(entry_finder)
         
     | 
| 
       7 
7 
     | 
    
         
             
                    @entry_finder = entry_finder
         
     | 
| 
         @@ -9,6 +9,7 @@ module QRDA 
     | 
|
| 
       9 
9 
     | 
    
         
             
                    @entry_id_map = {}
         
     | 
| 
       10 
10 
     | 
    
         
             
                    @check_for_usable = true
         
     | 
| 
       11 
11 
     | 
    
         
             
                    @entry_class = QDM::DataElement
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @warnings = []
         
     | 
| 
       12 
13 
     | 
    
         
             
                  end
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
15 
     | 
    
         
             
                  # Traverses an HL7 CDA document passed in and creates an Array of Entry
         
     | 
| 
         @@ -112,6 +113,19 @@ module QRDA 
     | 
|
| 
       112 
113 
     | 
    
         
             
                      low_time = Time.parse(parent_element.at_xpath("#{interval_xpath}/cda:center")['value'])
         
     | 
| 
       113 
114 
     | 
    
         
             
                      high_time = Time.parse(parent_element.at_xpath("#{interval_xpath}/cda:center")['value'])
         
     | 
| 
       114 
115 
     | 
    
         
             
                    end
         
     | 
| 
      
 116 
     | 
    
         
            +
                    if low_time && high_time && low_time > high_time
         
     | 
| 
      
 117 
     | 
    
         
            +
                      # pass warning: current code continues as expected, but adds warning
         
     | 
| 
      
 118 
     | 
    
         
            +
                      id_attr = parent_element.at_xpath(".//cda:id").attributes
         
     | 
| 
      
 119 
     | 
    
         
            +
                      qrda_type = @entry_class.to_s.split("::")[1]
         
     | 
| 
      
 120 
     | 
    
         
            +
                      @warnings << ValidationError.new(message: "Interval with low time after high time. Located in element with QRDA type: #{qrda_type} and id: #{id_attr['root']&.value}(root), #{id_attr['extension']&.value}(extension).",
         
     | 
| 
      
 121 
     | 
    
         
            +
                                                       location: parent_element.path)
         
     | 
| 
      
 122 
     | 
    
         
            +
                    end
         
     | 
| 
      
 123 
     | 
    
         
            +
                    if low_time.nil? && high_time.nil?
         
     | 
| 
      
 124 
     | 
    
         
            +
                      id_attr = parent_element.at_xpath(".//cda:id").attributes
         
     | 
| 
      
 125 
     | 
    
         
            +
                      qrda_type = @entry_class.to_s.split("::")[1]
         
     | 
| 
      
 126 
     | 
    
         
            +
                      @warnings << ValidationError.new(message: "Interval with nullFlavor low time and nullFlavor high time. Located in element with QRDA type: #{qrda_type} and id: #{id_attr['root']&.value}(root), #{id_attr['extension']&.value if id_attr['extension']}(extension).",
         
     | 
| 
      
 127 
     | 
    
         
            +
                                                       location: parent_element.path)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    end
         
     | 
| 
       115 
129 
     | 
    
         
             
                    QDM::Interval.new(low_time, high_time).shift_dates(0)
         
     | 
| 
       116 
130 
     | 
    
         
             
                  end
         
     | 
| 
       117 
131 
     | 
    
         | 
| 
         @@ -167,6 +181,10 @@ module QRDA 
     | 
|
| 
       167 
181 
     | 
    
         
             
                    elsif value_element['code'].present?
         
     | 
| 
       168 
182 
     | 
    
         
             
                      return code_if_present(value_element)
         
     | 
| 
       169 
183 
     | 
    
         
             
                    elsif value_element.text.present?
         
     | 
| 
      
 184 
     | 
    
         
            +
                      id_attr = value_element.parent.at_xpath(".//cda:id").attributes
         
     | 
| 
      
 185 
     | 
    
         
            +
                      qrda_type = @entry_class.to_s.split("::")[1]
         
     | 
| 
      
 186 
     | 
    
         
            +
                      @warnings << ValidationError.new(message: "Value with string type found. When possible, it's best practice to use a coded value or scalar. Located in element with QRDA type: #{qrda_type} and id: #{id_attr['root']&.value}(root), #{id_attr['extension']&.value}(extension).",
         
     | 
| 
      
 187 
     | 
    
         
            +
                                                       location: value_element.path)
         
     | 
| 
       170 
188 
     | 
    
         
             
                      return value_element.text
         
     | 
| 
       171 
189 
     | 
    
         
             
                    end
         
     | 
| 
       172 
190 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -194,8 +212,17 @@ module QRDA 
     | 
|
| 
       194 
212 
     | 
    
         
             
                  def extract_negated_code(parent_element, entry)
         
     | 
| 
       195 
213 
     | 
    
         
             
                    code_elements = parent_element.xpath(@code_xpath)
         
     | 
| 
       196 
214 
     | 
    
         
             
                    code_elements.each do |code_element|
         
     | 
| 
       197 
     | 
    
         
            -
                      if code_element['nullFlavor'] == 'NA' 
     | 
| 
       198 
     | 
    
         
            -
                         
     | 
| 
      
 215 
     | 
    
         
            +
                      if code_element['nullFlavor'] == 'NA'
         
     | 
| 
      
 216 
     | 
    
         
            +
                        if code_element['sdtc:valueSet']
         
     | 
| 
      
 217 
     | 
    
         
            +
                          entry.dataElementCodes = [{ code: code_element['sdtc:valueSet'], system: '1.2.3.4.5.6.7.8.9.10' }]
         
     | 
| 
      
 218 
     | 
    
         
            +
                        else
         
     | 
| 
      
 219 
     | 
    
         
            +
                          # negated code is nullFlavored with no valueset
         
     | 
| 
      
 220 
     | 
    
         
            +
                          entry.dataElementCodes = [{ code: "NA", system: '1.2.3.4.5.6.7.8.9.10' }]
         
     | 
| 
      
 221 
     | 
    
         
            +
                          id_attr = parent_element.at_xpath(".//cda:id").attributes
         
     | 
| 
      
 222 
     | 
    
         
            +
                          qrda_type = @entry_class.to_s.split("::")[1]
         
     | 
| 
      
 223 
     | 
    
         
            +
                          @warnings << ValidationError.new(message: "Negated code element contains nullFlavor code but no valueset. Located in element with QRDA type: #{qrda_type} and id: #{id_attr['root']&.value}(root), #{id_attr['extension']&.value}(extension).",
         
     | 
| 
      
 224 
     | 
    
         
            +
                                                           location: parent_element.path)
         
     | 
| 
      
 225 
     | 
    
         
            +
                        end
         
     | 
| 
       199 
226 
     | 
    
         
             
                      end
         
     | 
| 
       200 
227 
     | 
    
         
             
                    end
         
     | 
| 
       201 
228 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -12,70 +12,71 @@ module QRDA 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  def initialize
         
     | 
| 
       13 
13 
     | 
    
         
             
                    # This differs from other HDS patient importers in that sections can have multiple importers
         
     | 
| 
       14 
14 
     | 
    
         
             
                    @data_element_importers = []
         
     | 
| 
       15 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       16 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       17 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       18 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       19 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       20 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       21 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       22 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       23 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       24 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       25 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       26 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       27 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       28 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       29 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       30 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       31 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       32 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       33 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       34 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       35 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       36 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       37 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       38 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       39 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       40 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       41 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       42 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       43 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       44 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       45 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       46 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       47 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       48 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       49 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       50 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       51 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       52 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       53 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       54 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       55 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       56 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       57 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       58 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       59 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       60 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       61 
     | 
    
         
            -
                    @data_element_importers <<  
     | 
| 
       62 
     | 
    
         
            -
                  end 
     | 
| 
      
 15 
     | 
    
         
            +
                    @data_element_importers << AdverseEventImporter.new
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @data_element_importers << AllergyIntoleranceImporter.new
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @data_element_importers << AssessmentOrderImporter.new
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @data_element_importers << AssessmentPerformedImporter.new
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @data_element_importers << AssessmentRecommendedImporter.new
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @data_element_importers << CommunicationPerformedImporter.new
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @data_element_importers << DeviceAppliedImporter.new
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @data_element_importers << DeviceOrderImporter.new
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @data_element_importers << DeviceRecommendedImporter.new
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @data_element_importers << DiagnosisImporter.new
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @data_element_importers << DiagnosticStudyOrderImporter.new
         
     | 
| 
      
 26 
     | 
    
         
            +
                    @data_element_importers << DiagnosticStudyPerformedImporter.new
         
     | 
| 
      
 27 
     | 
    
         
            +
                    @data_element_importers << DiagnosticStudyRecommendedImporter.new
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @data_element_importers << EncounterOrderImporter.new
         
     | 
| 
      
 29 
     | 
    
         
            +
                    @data_element_importers << EncounterPerformedImporter.new
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @data_element_importers << EncounterRecommendedImporter.new
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @data_element_importers << FamilyHistoryImporter.new
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @data_element_importers << ImmunizationAdministeredImporter.new
         
     | 
| 
      
 33 
     | 
    
         
            +
                    @data_element_importers << ImmunizationOrderImporter.new
         
     | 
| 
      
 34 
     | 
    
         
            +
                    @data_element_importers << InterventionOrderImporter.new
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @data_element_importers << InterventionPerformedImporter.new
         
     | 
| 
      
 36 
     | 
    
         
            +
                    @data_element_importers << InterventionRecommendedImporter.new
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @data_element_importers << LaboratoryTestOrderImporter.new
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @data_element_importers << LaboratoryTestPerformedImporter.new
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @data_element_importers << LaboratoryTestRecommendedImporter.new
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @data_element_importers << MedicationActiveImporter.new
         
     | 
| 
      
 41 
     | 
    
         
            +
                    @data_element_importers << MedicationAdministeredImporter.new
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @data_element_importers << MedicationDischargeImporter.new
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @data_element_importers << MedicationDispensedImporter.new
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @data_element_importers << MedicationOrderImporter.new
         
     | 
| 
      
 45 
     | 
    
         
            +
                    @data_element_importers << PatientCareExperienceImporter.new
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @data_element_importers << PatientCharacteristicClinicalTrialParticipantImporter.new
         
     | 
| 
      
 47 
     | 
    
         
            +
                    @data_element_importers << PatientCharacteristicExpiredImporter.new
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @data_element_importers << PatientCharacteristicPayerImporter.new
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @data_element_importers << PhysicalExamOrderImporter.new
         
     | 
| 
      
 50 
     | 
    
         
            +
                    @data_element_importers << PhysicalExamPerformedImporter.new
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @data_element_importers << PhysicalExamRecommendedImporter.new
         
     | 
| 
      
 52 
     | 
    
         
            +
                    @data_element_importers << ProcedureOrderImporter.new
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @data_element_importers << ProcedurePerformedImporter.new
         
     | 
| 
      
 54 
     | 
    
         
            +
                    @data_element_importers << ProcedureRecommendedImporter.new
         
     | 
| 
      
 55 
     | 
    
         
            +
                    @data_element_importers << ProgramParticipationImporter.new
         
     | 
| 
      
 56 
     | 
    
         
            +
                    @data_element_importers << ProviderCareExperienceImporter.new
         
     | 
| 
      
 57 
     | 
    
         
            +
                    @data_element_importers << RelatedPersonImporter.new
         
     | 
| 
      
 58 
     | 
    
         
            +
                    @data_element_importers << SubstanceAdministeredImporter.new
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @data_element_importers << SubstanceOrderImporter.new
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @data_element_importers << SubstanceRecommendedImporter.new
         
     | 
| 
      
 61 
     | 
    
         
            +
                    @data_element_importers << SymptomImporter.new
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
       64 
64 
     | 
    
         
             
                  def parse_cat1(doc)
         
     | 
| 
       65 
65 
     | 
    
         
             
                    patient = CQM::Patient.new
         
     | 
| 
      
 66 
     | 
    
         
            +
                    warnings = []
         
     | 
| 
       66 
67 
     | 
    
         
             
                    entry_id_map = {}
         
     | 
| 
       67 
     | 
    
         
            -
                    import_data_elements(patient, doc, entry_id_map)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    import_data_elements(patient, doc, entry_id_map, warnings)
         
     | 
| 
       68 
69 
     | 
    
         
             
                    normalize_references(patient, entry_id_map)
         
     | 
| 
       69 
70 
     | 
    
         
             
                    get_demographics(patient, doc)
         
     | 
| 
       70 
     | 
    
         
            -
                    patient
         
     | 
| 
      
 71 
     | 
    
         
            +
                    [patient, warnings]
         
     | 
| 
       71 
72 
     | 
    
         
             
                  end
         
     | 
| 
       72 
73 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
                  def import_data_elements(patient, doc, entry_id_map)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  def import_data_elements(patient, doc, entry_id_map, warnings = [])
         
     | 
| 
       74 
75 
     | 
    
         
             
                    context = doc.xpath("/cda:ClinicalDocument/cda:component/cda:structuredBody/cda:component/cda:section[cda:templateId/@root = '2.16.840.1.113883.10.20.24.2.1']")
         
     | 
| 
       75 
76 
     | 
    
         
             
                    nrh = NarrativeReferenceHandler.new
         
     | 
| 
       76 
77 
     | 
    
         
             
                    nrh.build_id_map(doc)
         
     | 
| 
       77 
     | 
    
         
            -
                    @data_element_importers.each do | 
     | 
| 
       78 
     | 
    
         
            -
                      data_elements, id_map =  
     | 
| 
      
 78 
     | 
    
         
            +
                    @data_element_importers.each do |importer|
         
     | 
| 
      
 79 
     | 
    
         
            +
                      data_elements, id_map = importer.create_entries(context, nrh)
         
     | 
| 
       79 
80 
     | 
    
         
             
                      new_data_elements = []
         
     | 
| 
       80 
81 
     | 
    
         | 
| 
       81 
82 
     | 
    
         
             
                      id_map.each_value do |elem_ids|
         
     | 
| 
         @@ -92,7 +93,7 @@ module QRDA 
     | 
|
| 
       92 
93 
     | 
    
         
             
                        unique_element_keys << key_elements_for_determining_encounter_uniqueness(data_element)
         
     | 
| 
       93 
94 
     | 
    
         | 
| 
       94 
95 
     | 
    
         
             
                        # Loop through all other data elements with the same id
         
     | 
| 
       95 
     | 
    
         
            -
                        elem_ids[1,elem_ids.length].each do |dup_id| 
     | 
| 
      
 96 
     | 
    
         
            +
                        elem_ids[1,elem_ids.length].each do |dup_id|
         
     | 
| 
       96 
97 
     | 
    
         
             
                          dup_element = data_elements.find { |de| de.id == dup_id }
         
     | 
| 
       97 
98 
     | 
    
         
             
                          dup_element_keys = key_elements_for_determining_encounter_uniqueness(dup_element)
         
     | 
| 
       98 
99 
     | 
    
         
             
                          # See if a previously selected data element shared all of the keys files
         
     | 
| 
         @@ -107,6 +108,9 @@ module QRDA 
     | 
|
| 
       107 
108 
     | 
    
         | 
| 
       108 
109 
     | 
    
         
             
                      patient.qdmPatient.dataElements << new_data_elements
         
     | 
| 
       109 
110 
     | 
    
         
             
                      entry_id_map.merge!(id_map)
         
     | 
| 
      
 111 
     | 
    
         
            +
                      warnings.concat(importer.warnings)
         
     | 
| 
      
 112 
     | 
    
         
            +
                      # reset warnings after they're captured so that the importer can be re-used
         
     | 
| 
      
 113 
     | 
    
         
            +
                      importer.warnings = []
         
     | 
| 
       110 
114 
     | 
    
         
             
                    end
         
     | 
| 
       111 
115 
     | 
    
         
             
                  end
         
     | 
| 
       112 
116 
     | 
    
         | 
| 
         @@ -136,12 +140,6 @@ module QRDA 
     | 
|
| 
       136 
140 
     | 
    
         
             
                      data_element.relatedTo = relations_to_add.map(&:to_s)
         
     | 
| 
       137 
141 
     | 
    
         
             
                    end
         
     | 
| 
       138 
142 
     | 
    
         
             
                  end
         
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
                  private
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                  def generate_importer(importer_class)
         
     | 
| 
       143 
     | 
    
         
            -
                    EntryPackage.new(importer_class.new)
         
     | 
| 
       144 
     | 
    
         
            -
                  end
         
     | 
| 
       145 
143 
     | 
    
         
             
                end
         
     | 
| 
       146 
144 
     | 
    
         
             
              end
         
     | 
| 
       147 
145 
     | 
    
         
             
            end
         
     | 
    
        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: 3.0 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 3.1.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: 2020-07- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-07-15 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: cqm-models
         
     | 
| 
         @@ -24,6 +24,20 @@ dependencies: 
     | 
|
| 
       24 
24 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       25 
25 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       26 
26 
     | 
    
         
             
                    version: 3.0.0
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: cqm-validators
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: 3.0.0
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: 3.0.0
         
     | 
| 
       27 
41 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       28 
42 
     | 
    
         
             
              name: mustache
         
     | 
| 
       29 
43 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -314,7 +328,6 @@ files: 
     | 
|
| 
       314 
328 
     | 
    
         
             
            - lib/qrda-import/data-element-importers/substance_recommended_importer.rb
         
     | 
| 
       315 
329 
     | 
    
         
             
            - lib/qrda-import/data-element-importers/symptom_importer.rb
         
     | 
| 
       316 
330 
     | 
    
         
             
            - lib/qrda-import/entry_finder.rb
         
     | 
| 
       317 
     | 
    
         
            -
            - lib/qrda-import/entry_package.rb
         
     | 
| 
       318 
331 
     | 
    
         
             
            - lib/qrda-import/narrative_reference_handler.rb
         
     | 
| 
       319 
332 
     | 
    
         
             
            - lib/qrda-import/patient_importer.rb
         
     | 
| 
       320 
333 
     | 
    
         
             
            - lib/util/code_system_helper.rb
         
     |