<commit_before>require 'json'
require_relative '../../lib/provider_import_utils'

class CcdaController < ApplicationController

  def create
    doc = Nokogiri::XML(request.body)

    doc.root.add_namespace_definition('cda', 'urn:hl7-org:v3')
    doc.root.add_namespace_definition('sdtc', 'urn:hl7-org:sdtc')

    root_element_name = doc.root.name

    if root_element_name == 'ClinicalDocument'
      if doc.at_xpath("/cda:ClinicalDocument/cda:templateId[@root='2.16.840.1.113883.3.88.11.32.1']")
          patient_data =  HealthDataStandards::Import::C32::PatientImporter.instance.parse_c32(doc)
      elsif doc.at_xpath("/cda:ClinicalDocument/cda:templateId[@root='2.16.840.1.113883.10.20.22.1.2']")
          # Fix encounter codes that have null code but predictable originalText
          enc_codes = doc.xpath("/cda:ClinicalDocument/cda:component/cda:structuredBody/cda:component/cda:section/cda:entry/cda:encounter/cda:code")
          enc_codes.each do | enc_code |
            if !enc_code.nil? && enc_code['nullFlavor'] == "UNK" && enc_code['code'].nil?
              original_text = enc_code.at_xpath("cda:originalText").text
              case original_text
              when 'Emergency'
                enc_code.delete 'nullFlavor'
                enc_code['code'] = '50849002'
                enc_code['codeSystem'] = '2.16.840.1.113883.6.96'
                enc_code['codeSystemName'] = 'SNOMED-CT'
                enc_code['displayName'] = 'Emergency room admission'
              when 'Inpatient'
                enc_code.delete 'nullFlavor'
                enc_code['code'] = '32485007'
                enc_code['codeSystem'] = '2.16.840.1.113883.6.96'
                enc_code['codeSystemName'] = 'SNOMED-CT'
                enc_code['displayName'] = 'Hospital admission'
              when 'Observation'
                enc_code.delete 'nullFlavor'
                enc_code['code'] = '448951000124107'
                enc_code['codeSystem'] = '2.16.840.1.113883.6.96'
                enc_code['codeSystemName'] = 'SNOMED-CT'
                enc_code['displayName'] = 'Admission to observation unit'
              else
                puts "Cannot infer encounter code from unrecognized originalText: #{original_text}"
              end
            end
          end
          patient_data =  HealthDataStandards::Import::CCDA::PatientImporter.instance.parse_ccda(doc)
      end
    end

    # TODO: Fix encounter codes that have no code

    patient_json = patient_data.to_json

    File.open('patient.json', 'w+') do |f|
      f.write(patient_json)
    end

    FhirUploadJob.perform_later(patient_json)
    render nothing: true
  end

end<commit_msg>Refactor encounter code inference to reduce duplication and to set description when it isn't available<commit_after>require 'json'
require_relative '../../lib/provider_import_utils'

class CcdaController < ApplicationController

  def create
    doc = Nokogiri::XML(request.body)

    doc.root.add_namespace_definition('cda', 'urn:hl7-org:v3')
    doc.root.add_namespace_definition('sdtc', 'urn:hl7-org:sdtc')

    root_element_name = doc.root.name

    if root_element_name == 'ClinicalDocument'
      if doc.at_xpath("/cda:ClinicalDocument/cda:templateId[@root='2.16.840.1.113883.3.88.11.32.1']")
          patient_data =  HealthDataStandards::Import::C32::PatientImporter.instance.parse_c32(doc)
      elsif doc.at_xpath("/cda:ClinicalDocument/cda:templateId[@root='2.16.840.1.113883.10.20.22.1.2']")
          # Fix encounter codes that have null code but predictable originalText
          enc_codes = doc.xpath("/cda:ClinicalDocument/cda:component/cda:structuredBody/cda:component/cda:section/cda:entry/cda:encounter/cda:code")
          enc_codes.each do | enc_code |
            if !enc_code.nil? && enc_code['nullFlavor'] == "UNK" && enc_code['code'].nil?
              self.fix_encounter_code(enc_code)
            end
          end
          patient_data =  HealthDataStandards::Import::CCDA::PatientImporter.instance.parse_ccda(doc)
      end
    end

    # TODO: Fix encounter codes that have no code

    patient_json = patient_data.to_json

    File.open('patient.json', 'w+') do |f|
      f.write(patient_json)
    end

    FhirUploadJob.perform_later(patient_json)
    render nothing: true
  end

  def fix_encounter_code(enc_code)
    text = enc_code.parent.at_xpath("cda:text")
    original_text = enc_code.at_xpath("cda:originalText").text
    case original_text
    when 'Emergency'
      insert_code(enc_code, '50849002', text, original_text)
    when 'Inpatient'
      insert_code(enc_code, '32485007', text, original_text)
    when 'Observation'
      insert_code(enc_code, '448951000124107', text, original_text)
    else
      puts "Cannot infer encounter code from unrecognized originalText: #{original_text}"
    end
  end

  def insert_code(code_node, code, text_node, description)
    code_node.delete 'nullFlavor'
    code_node['code'] = code
    code_node['codeSystem'] = '2.16.840.1.113883.6.96'
    code_node['codeSystemName'] = 'SNOMED-CT'
    if text_node.nil?
      code_node.add_next_sibling "<text>#{description}</text>"
    elsif text_node.content.strip.blank? && text_node.children.empty?
      text_node.content = description
    end
  end
end
{'fraction_non_alphanumeric': 0.1200076074553062, 'fraction_numerical': 0.04260174971472042, 'mean_word_length': 2.990136570561457, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3726437', 'n_tokens_mistral': 1863, 'n_tokens_neox': 1700, 'n_words': 283}