# frozen_string_literal: true module MalawiHivProgramReports module Moh # This class is used to add additional cohort disaggregated data # rubocop:disable Metrics/ClassLength class CohortSurvivalAnalysis def initialize(name:, type:, start_date:, end_date:, regenerate:, occupation:) @name = name @type = type @start_date = start_date @end_date = end_date @regenerate = regenerate @occupation = occupation end def survival_analysis(quarter, age_group) art_service = CohortDisaggregated.new(name: 'survival_analysis', type: 'survival_analysis', start_date: Date.today, end_date: Date.today, rebuild: @regenerate) start_date, end_date = art_service.generate_start_date_and_end_date(quarter) CohortBuilder.new.init_temporary_tables(start_date, @end_date, @occupation) if @regenerate art_service = CohortDisaggregated.new(name: 'survival_analysis', type: 'survival_analysis', start_date: @start_date.to_date, end_date: @end_date.to_date, rebuild: @regenerate) qtr = quarter.split[0] results = {} years = 1 years_to_backto = ActiveRecord::Base.connection.select_one <<~SQL SELECT TIMESTAMPDIFF(YEAR, DATE(MIN(encounter_datetime)), DATE('#{end_date}')) years FROM encounter e WHERE program_id = 1 AND voided = 0; SQL clinic_start_years = begin years_to_backto['years'].to_i rescue StandardError nil end clinic_start_years = 10 if clinic_start_years.blank? while years < clinic_start_years yr = (quarter.split[1].to_i - years) set_qtr = "#{qtr} #{yr}" qstart_date, qend_date = art_service.generate_start_date_and_end_date(set_qtr) results[set_qtr] = {} case age_group when 'General' additional_sql = ' GROUP BY e.patient_id' when 'Children' additional_sql = ' GROUP BY e.patient_id' additional_sql += ' HAVING patient_age < 15' when 'Women' option_Bplus_women_ids = pregnant_and_breastfeeding_women(qstart_date, qend_date) option_Bplus_women_ids = [0] if option_Bplus_women_ids.blank? additional_sql = " AND e.patient_id IN (#{option_Bplus_women_ids.join(', ')})" additional_sql += ' GROUP BY e.patient_id' additional_sql += ' HAVING patient_age >= 15' additional_sql += ' AND gender = "F"' end begin data = ActiveRecord::Base.connection.select_all <<~SQL SELECT cum_outcome, timestampdiff(month, DATE('#{qend_date}'), DATE('#{end_date}')) qinterval, timestampdiff(year, DATE(e.birthdate), DATE('#{end_date}')) AS patient_age, e.gender FROM temp_earliest_start_date e INNER JOIN temp_patient_outcomes o ON o.patient_id = e.patient_id WHERE date_enrolled BETWEEN '#{qstart_date.strftime('%Y-%m-%d')}' AND '#{qend_date.strftime('%Y-%m-%d')}' #{additional_sql}; SQL rescue StandardError return results end (data || []).each do |r| outcome = r['cum_outcome'] outcome = (outcome.blank? ? 'Unknown' : outcome) if results[set_qtr][outcome].blank? results[set_qtr][outcome] = {} results[set_qtr][outcome][r['qinterval']] = 0 end results[set_qtr][outcome][r['qinterval']] += 1 end years += 1 end append_last_six_months(quarter, results, end_date) if age_group == 'Women' results end def pregnant_and_breastfeeding_women(start_date, end_date) patient_ids = [] patients = ActiveRecord::Base.connection.select_all <<~SQL SELECT e.*, patient_reason_for_starting_art_text(e.patient_id) reason FROM temp_earliest_start_date e WHERE date_enrolled BETWEEN '#{start_date.to_date}' AND '#{end_date.to_date}' AND gender IN('F','Female') GROUP BY e.patient_id HAVING reason LIKE '%pregnant%' OR reason LIKE '%breast%'; SQL (patients || []).each do |aRow| patient_ids << aRow['patient_id'].to_i end concept_ids = [] ::ConceptName.where(name: 'Breastfeeding').select do |c| concept_ids << c.concept_id end concept_ids << ::ConceptName.find_by_name('Patient pregnant').concept_id concept_ids << ::ConceptName.find_by_name('Is patient pregnant?').concept_id concept_ids << ::ConceptName.find_by_name('Is patient breast feeding?').concept_id yes_concept_id = ::ConceptName.find_by_name('Yes').concept_id patients = ActiveRecord::Base.connection.select_all <<~SQL SELECT e.*, patient_reason_for_starting_art_text(e.patient_id) reason FROM temp_earliest_start_date e INNER JOIN obs ON obs.person_id = e.patient_id WHERE date_enrolled BETWEEN '#{start_date.to_date}' AND '#{end_date.to_date}' AND gender IN('F','Female') AND obs.voided = 0 AND DATE(obs_datetime) = DATE(earliest_start_date) AND obs.concept_id IN(#{concept_ids.join(',')}) AND value_coded = #{yes_concept_id} GROUP BY e.patient_id HAVING reason LIKE '%Lymphocyte count below threshold with who stage%' ORDER BY obs_datetime DESC; SQL pregnant_and_breastfeeding_clients = [] (patients || []).each do |aRow| pregnant_and_breastfeeding_clients << aRow['patient_id'].to_i end (patient_ids + pregnant_and_breastfeeding_clients).uniq end def append_last_six_months(quarter, results, end_date) art_service = CohortDisaggregated.new(name: 'survival_analysis', type: 'survival_analysis', start_date: @start_date.to_date, end_date: @end_date.to_date, rebuild: @regenerate) qstart_date, qend_date = art_service.generate_start_date_and_end_date(quarter) qstart_date -= 6.month qend_date -= 6.month # set_qtr = "Q#{quarter.split(' ')[0][1..1].to_i - 2} #{qend_date.year}" set_qtr = (quarter[1..1].to_i - 2) set_qtr = (set_qtr.zero? ? 4 : set_qtr) set_qtr = (set_qtr == -1 ? 3 : set_qtr) set_qtr = (set_qtr == -2 ? 2 : set_qtr) set_qtr = "Q#{set_qtr} #{qend_date.year}" option_Bplus_women_ids = pregnant_and_breastfeeding_women(qstart_date, qend_date) option_Bplus_women_ids = [0] if option_Bplus_women_ids.blank? data = ActiveRecord::Base.connection.select_all <<~SQL SELECT cum_outcome, timestampdiff(month, DATE('#{qend_date}'), DATE('#{end_date}')) qinterval, timestampdiff(year, DATE(e.birthdate), DATE('#{end_date}')) AS patient_age, e.gender FROM temp_earliest_start_date e INNER JOIN temp_patient_outcomes o ON o.patient_id = e.patient_id WHERE date_enrolled BETWEEN '#{qstart_date.strftime('%Y-%m-%d')}' AND '#{qend_date.strftime('%Y-%m-%d')}' AND gender = 'F' AND e.patient_id IN (#{option_Bplus_women_ids.join(', ')}); SQL (data || []).each do |r| outcome = r['cum_outcome'] outcome = (outcome.blank? ? 'Unknown' : outcome) if results[set_qtr].blank? results[set_qtr] = {} results[set_qtr][outcome] = {} results[set_qtr][outcome][r['qinterval']] = 0 elsif results[set_qtr][outcome].blank? results[set_qtr][outcome] = {} results[set_qtr][outcome][r['qinterval']] = 0 end puts "######### #{r['qinterval']}" results[set_qtr][outcome][r['qinterval']] += 1 end results end end # rubocop:enable Metrics/ClassLength end end