malawi_hiv_program_reports 1.1.16 → 1.1.17

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.
@@ -3,7 +3,7 @@
3
3
  module MalawiHivProgramReports
4
4
  module Pepfar
5
5
  class TxMl
6
- attr_reader :start_date, :end_date, :location, :rebuild
6
+ attr_reader :start_date, :end_date, :location, :report, :rebuild
7
7
 
8
8
  include Utils
9
9
  include MalawiHivProgramReports::Utils::CommonSqlQueryUtils
@@ -17,56 +17,140 @@ module MalawiHivProgramReports
17
17
  end
18
18
 
19
19
  def find_report
20
- if rebuild
21
- cohort = MalawiHivProgramReports::Moh::CumulativeCohort.new(start_date: start_date.to_date, end_date: end_date.to_date, definition: 'pepfar',
22
- locations: location.to_s, rebuild: true.to_s)
23
- cohort.find_report
24
- end
20
+ rebuild_outcomes if rebuild
21
+ init_report
22
+ addittional_groups
25
23
  process_data
24
+ flatten_the_report
26
25
  end
27
26
 
28
27
  private
29
28
 
29
+ def rebuild_outcomes
30
+ cohort = MalawiHivProgramReports::Moh::CumulativeCohort.new(start_date: start_date.to_date, end_date: end_date.to_date, definition: 'pepfar',
31
+ locations: location.to_s, rebuild: true.to_s)
32
+ cohort.find_report
33
+ end
34
+
35
+ def init_report
36
+ @report = initialize_report_structure
37
+ end
38
+
39
+ GENDER = %w[Male Female].freeze
40
+
41
+ def initialize_report_structure
42
+ pepfar_age_groups.each_with_object({}) do |age_group, report|
43
+ report[age_group] = GENDER.each_with_object({}) do |gender, age_group_report|
44
+ age_group_report[gender] = initialize_gender_metrics
45
+ end
46
+ end
47
+ end
48
+
49
+ def addittional_groups
50
+ @report['All'] = {}
51
+ %w[Male FP FNP FBf].each do |key|
52
+ @report['All'][key] = initialize_gender_metrics
53
+ end
54
+ end
55
+
56
+ def initialize_gender_metrics
57
+ {
58
+ died: [],
59
+ iit_less_3_months: [],
60
+ iit_3_to_5_months: [],
61
+ iit_6_plus_months: [],
62
+ transfer: [],
63
+ stopped: []
64
+ }
65
+ end
66
+
67
+ def flatten_the_report
68
+ result = []
69
+ @report.each do |age_group, age_group_report|
70
+ next if age_group == 'Unknown'
71
+
72
+ age_group_report.each_key do |gender|
73
+ next if gender == 'Unknown'
74
+
75
+ result << process_age_group_report(age_group, gender, age_group_report[gender])
76
+ end
77
+ end
78
+
79
+ new_group = pepfar_age_groups.map { |age_group| age_group }
80
+ new_group << 'All'
81
+ gender_scores = { 'Female' => 0, 'Male' => 1, 'FNP' => 3, 'FP' => 2, 'FBf' => 4 }
82
+ result_scores = result.sort_by do |item|
83
+ gender_score = gender_scores[item[:gender]] || 999
84
+ age_group_score = new_group.index(item[:age_group]) || 999
85
+ [gender_score, age_group_score]
86
+ end
87
+ # remove all unknown age groups
88
+ result_scores.reject { |item| item[:age_group].match?(/unknown/i) }
89
+ end
90
+
91
+ def process_age_group_report(age_group, gender, age_group_report)
92
+ {
93
+ age_group:,
94
+ gender:,
95
+ died: age_group_report[:died],
96
+ iit_less_3_months: age_group_report[:iit_less_3_months],
97
+ iit_3_to_5_months: age_group_report[:iit_3_to_5_months],
98
+ iit_6_plus_months: age_group_report[:iit_6_plus_months],
99
+ transfer: age_group_report[:transfer],
100
+ stopped: age_group_report[:stopped]
101
+ }
102
+ end
103
+
30
104
  def process_data
31
- data = {}
32
105
  (process_tx_ml_clients || []).each do |pat|
33
106
  patient_id = pat['patient_id'].to_i
34
107
  outcome = pat['outcome']
35
- gender = begin
36
- pat['gender'].first.upcase
37
- rescue StandardError
38
- 'Unknown'
39
- end
108
+ gender = pat['gender'] || 'Unknown'
40
109
  age_group = pat['age_group']
110
+ maternal_status = pat['maternal_status']
111
+ next unless gender.in?(%w[Male Female])
41
112
 
42
- if data[age_group].blank?
43
- data[age_group] = {}
44
- data[age_group][gender] = [[], [], [], [], [], []]
45
- elsif data[age_group][gender].blank?
46
- data[age_group][gender] = [[], [], [], [], [], []]
47
- end
113
+ indicator = process_outcome(outcome, pat['months'])
114
+ aggregation(patient_id, gender, indicator, maternal_status, age_group)
115
+ rescue StandardError => e
116
+ Rails.logger.error "Error processing patient: #{patient_id} - #{age_group} - #{gender} - #{outcome} - #{e.message}"
117
+ end
118
+ end
48
119
 
49
- case outcome
50
- when 'Defaulted'
51
- def_months = pat['months'].to_i
52
- if def_months < 3
53
- data[age_group][gender][1] << patient_id
54
- elsif def_months <= 5
55
- data[age_group][gender][2] << patient_id
56
- elsif def_months > 5
57
- data[age_group][gender][3] << patient_id
58
- end
59
- when 'Patient died'
60
- data[age_group][gender][0] << patient_id
61
- when /Stopped/i
62
- data[age_group][gender][5] << patient_id
63
- when 'Patient transferred out'
64
- data[age_group][gender][4] << patient_id
120
+ def process_outcome(outcome, months)
121
+ case outcome
122
+ when 'Defaulted'
123
+ if months < 3
124
+ 'iit_less_3_months'
125
+ elsif months <= 5
126
+ 'iit_3_to_5_months'
127
+ elsif months > 5
128
+ 'iit_6_plus_months'
65
129
  end
66
- rescue StandardError => e
67
- Rails.logger.error(e.message)
130
+ when 'Patient died'
131
+ 'died'
132
+ when /Stopped/i
133
+ 'stopped'
134
+ when 'Patient transferred out'
135
+ 'transfer'
136
+ end
137
+ end
138
+
139
+ def aggregation(patient_id, gender, indicator, maternal_status, age_group)
140
+ @report[age_group][gender][indicator.to_sym] << patient_id
141
+ if gender == 'Male'
142
+ @report['All'][gender][indicator.to_sym] << patient_id
143
+ return
144
+ end
145
+
146
+ case maternal_status
147
+ when 'FP'
148
+ @report['All']['FP'][indicator.to_sym] << patient_id
149
+ when 'FBf'
150
+ @report['All']['FBf'][indicator.to_sym] << patient_id
151
+ else
152
+ @report['All']['FNP'][indicator.to_sym] << patient_id
68
153
  end
69
- data
70
154
  end
71
155
 
72
156
  def tx_ml_clients
@@ -74,7 +158,12 @@ module MalawiHivProgramReports
74
158
  SELECT
75
159
  e.patient_id,
76
160
  e.birthdate,
77
- e.gender,
161
+ CASE e.gender
162
+ WHEN 'M' THEN 'Male'
163
+ WHEN 'F' THEN 'Female'
164
+ ELSE 'Unknown'
165
+ END gender,
166
+ c.maternal_status,
78
167
  e.date_enrolled,
79
168
  e.earliest_start_date,
80
169
  o.outcome_date,
@@ -82,7 +171,8 @@ module MalawiHivProgramReports
82
171
  disaggregated_age_group(e.birthdate, DATE('#{end_date}')) age_group,
83
172
  o.cum_outcome outcome
84
173
  FROM cdr_temp_cohort_members #{current_partition} e
85
- INNER JOIN cdr_temp_patient_outcomes #{current_partition} o ON e.patient_id = o.patient_id AND o.cum_outcome IN ('Defaulted', 'Patient died', 'Treatment stopped', 'Patient transferred out')
174
+ INNER JOIN cdr_temp_patient_outcomes #{current_partition} o ON e.patient_id = o.patient_id AND o.cum_outcome IN ('Defaulted', 'Patient died', 'Treatment Stopped', 'Patient transferred out')
175
+ LEFT JOIN cdr_temp_maternal_status #{current_partition} c ON c.patient_id = e.patient_id
86
176
  WHERE e.patient_id IN (SELECT patient_id FROM cdr_temp_patient_outcomes_start #{current_partition} WHERE cum_outcome = 'On antiretrovirals')
87
177
  AND DATE(e.earliest_start_date) < '#{start_date.to_date}'
88
178
  GROUP BY e.patient_id
@@ -94,7 +184,12 @@ module MalawiHivProgramReports
94
184
  SELECT
95
185
  e.patient_id,
96
186
  e.birthdate,
97
- e.gender,
187
+ CASE e.gender
188
+ WHEN 'M' THEN 'Male'
189
+ WHEN 'F' THEN 'Female'
190
+ ELSE 'Unknown'
191
+ END gender,
192
+ c.maternal_status,
98
193
  e.date_enrolled,
99
194
  e.earliest_start_date,
100
195
  o.outcome_date,
@@ -102,7 +197,8 @@ module MalawiHivProgramReports
102
197
  disaggregated_age_group(e.birthdate, DATE('#{end_date}')) age_group,
103
198
  o.cum_outcome outcome
104
199
  FROM cdr_temp_cohort_members #{current_partition} e
105
- INNER JOIN cdr_temp_patient_outcomes #{current_partition} o ON e.patient_id = o.patient_id AND o.cum_outcome IN ('Defaulted', 'Patient died', 'Treatment stopped', 'Patient transferred out')
200
+ INNER JOIN cdr_temp_patient_outcomes #{current_partition} o ON e.patient_id = o.patient_id AND o.cum_outcome IN ('Defaulted', 'Patient died', 'Treatment Stopped', 'Patient transferred out')
201
+ LEFT JOIN cdr_temp_maternal_status #{current_partition} c ON c.patient_id = e.patient_id
106
202
  WHERE e.earliest_start_date BETWEEN DATE('#{start_date}') AND DATE('#{end_date}')
107
203
  GROUP BY e.patient_id
108
204
  SQL
@@ -21,11 +21,7 @@ module MalawiHivProgramReports
21
21
  def find_report
22
22
  report = init_report
23
23
  addittional_groups report
24
- if rebuild
25
- cohort = MalawiHivProgramReports::Moh::CumulativeCohort.new(start_date: start_date.to_date, end_date: end_date.to_date, definition: 'pepfar',
26
- locations: location.to_s, rebuild: true.to_s)
27
- cohort.find_report
28
- end
24
+ process_rebuild if rebuild
29
25
  process_data report
30
26
  flatten_the_report report
31
27
  rescue StandardError => e
@@ -37,17 +33,18 @@ module MalawiHivProgramReports
37
33
 
38
34
  private
39
35
 
40
- GENDER = %w[M F].freeze
36
+ GENDER = %w[Male Female].freeze
37
+
38
+ def process_rebuild
39
+ cohort = MalawiHivProgramReports::Moh::CumulativeCohort.new(start_date: start_date.to_date, end_date: end_date.to_date, definition: 'pepfar',
40
+ locations: location.to_s, rebuild: true.to_s)
41
+ cohort.find_report
42
+ end
41
43
 
42
44
  def init_report
43
45
  pepfar_age_groups.each_with_object({}) do |age_group, report|
44
46
  report[age_group] = GENDER.each_with_object({}) do |gender, age_group_report|
45
- age_group_report[gender] = {
46
- cd4_less_than_200: [],
47
- cd4_greater_than_equal_to_200: [],
48
- cd4_unknown_or_not_done: [],
49
- transfer_in: []
50
- }
47
+ age_group_report[gender] = initialize_gender_metrics
51
48
  end
52
49
  end
53
50
  end
@@ -55,15 +52,19 @@ module MalawiHivProgramReports
55
52
  def addittional_groups(report)
56
53
  report['All'] = {}
57
54
  %w[Male FP FNP FBf].each do |key|
58
- report['All'][key] = {
59
- cd4_less_than_200: [],
60
- cd4_greater_than_equal_to_200: [],
61
- cd4_unknown_or_not_done: [],
62
- transfer_in: []
63
- }
55
+ report['All'][key] = initialize_gender_metrics
64
56
  end
65
57
  end
66
58
 
59
+ def initialize_gender_metrics
60
+ {
61
+ cd4_less_than_200: [],
62
+ cd4_greater_than_equal_to_200: [],
63
+ cd4_unknown_or_not_done: [],
64
+ transfer_in: []
65
+ }
66
+ end
67
+
67
68
  # rubocop:disable Metrics/AbcSize
68
69
  # rubocop:disable Metrics/MethodLength
69
70
  # rubocop:disable Metrics/PerceivedComplexity
@@ -72,7 +73,6 @@ module MalawiHivProgramReports
72
73
  fetch_data.each do |row|
73
74
  age_group = row['age_group']
74
75
  gender = row['gender']
75
- date_enrolled = row['date_enrolled']
76
76
  next if age_group.blank?
77
77
  next if gender.blank?
78
78
  next unless GENDER.include?(gender)
@@ -83,32 +83,36 @@ module MalawiHivProgramReports
83
83
  patient_id = row['patient_id'].to_i
84
84
  earliest_start_date = row['earliest_start_date']
85
85
  indicator = new_patient.positive? ? cd4_count_group : 'transfer_in'
86
+ maternal_status = row['maternal_status']
86
87
 
87
- if new_patient.positive? && earliest_start_date.to_date >= start_date.to_date
88
- report[age_group.to_s][gender.to_s][indicator.to_sym] << patient_id
89
- elsif new_patient.zero?
90
- report[age_group.to_s][gender.to_s][indicator.to_sym] << patient_id
91
- else
92
- next
93
- end
94
- process_aggreggation_rows(report:, gender:, indicator:, start_date: date_enrolled,
95
- patient_id:, maternal_status: row['maternal_status'], maternal_status_date: row['maternal_status_date'])
88
+ next if !(new_patient.positive? && earliest_start_date.to_date >= start_date.to_date) && !new_patient.zero?
89
+
90
+ process_aggreggation_rows(report:, gender:, indicator:, patient_id:, maternal_status:, age_group:)
96
91
  end
97
92
  end
98
93
 
99
- def process_aggreggation_rows(report:, gender:, indicator:, start_date:, **kwargs)
94
+ def process_aggreggation_rows(report:, gender:, indicator:, **kwargs)
100
95
  maternal_status = kwargs[:maternal_status]
101
- maternal_status_date = kwargs[:maternal_status_date]
96
+ age_group = kwargs[:age_group]
97
+ report[age_group][gender][indicator.to_sym] << kwargs[:patient_id]
102
98
 
103
- if gender == 'M'
99
+ if gender == 'Male'
104
100
  report['All']['Male'][indicator.to_sym] << kwargs[:patient_id]
105
- elsif maternal_status&.match?(/pregnant/i) && (maternal_status_date&.to_date&.<= start_date.to_date)
101
+ return
102
+ end
103
+
104
+ case maternal_status
105
+ when 'FP'
106
106
  report['All']['FP'][indicator.to_sym] << kwargs[:patient_id]
107
- elsif maternal_status&.match?(/breast/i) && (maternal_status_date&.to_date&.<= start_date.to_date)
107
+ when 'FBf'
108
108
  report['All']['FBf'][indicator.to_sym] << kwargs[:patient_id]
109
109
  else
110
110
  report['All']['FNP'][indicator.to_sym] << kwargs[:patient_id]
111
111
  end
112
+ rescue StandardError => e
113
+ Rails.logger.error "Error processing patient: #{kwargs[:patient_id]} - #{gender} - #{indicator} - #{kwargs[:maternal_status]} - #{e.message}"
114
+ Rails.logger.error report
115
+ raise e
112
116
  end
113
117
  # rubocop:enable Metrics/PerceivedComplexity
114
118
  # rubocop:enable Metrics/CyclomaticComplexity
@@ -116,15 +120,8 @@ module MalawiHivProgramReports
116
120
  def process_age_group_report(age_group, gender, age_group_report)
117
121
  {
118
122
  age_group:,
119
- gender: if gender == 'F'
120
- 'Female'
121
- else
122
- (gender == 'M' ? 'Male' : gender)
123
- end,
124
- cd4_less_than_200: age_group_report[:cd4_less_than_200],
125
- cd4_greater_than_equal_to_200: age_group_report[:cd4_greater_than_equal_to_200],
126
- cd4_unknown_or_not_done: age_group_report[:cd4_unknown_or_not_done],
127
- transfer_in: age_group_report[:transfer_in]
123
+ gender:,
124
+ **age_group_report
128
125
  }
129
126
  end
130
127
  # rubocop:enable Metrics/AbcSize
@@ -133,6 +130,8 @@ module MalawiHivProgramReports
133
130
  def flatten_the_report(report)
134
131
  result = []
135
132
  report.each do |age_group, age_group_report|
133
+ next if age_group == 'Unknown'
134
+
136
135
  age_group_report.each_key do |gender|
137
136
  result << process_age_group_report(age_group, gender, age_group_report[gender])
138
137
  end
@@ -154,7 +153,11 @@ module MalawiHivProgramReports
154
153
  ActiveRecord::Base.connection.select_all <<~SQL
155
154
  SELECT
156
155
  e.patient_id,
157
- e.gender,
156
+ CASE e.gender
157
+ WHEN 'M' THEN 'Male'
158
+ WHEN 'F' THEN 'Female'
159
+ ELSE 'Unknown'
160
+ END gender,
158
161
  disaggregated_age_group(e.birthdate, DATE('#{end_date}')) age_group,
159
162
  CASE
160
163
  WHEN o.value_numeric < 200 THEN 'cd4_less_than_200'
@@ -170,28 +173,12 @@ module MalawiHivProgramReports
170
173
  END new_patient,
171
174
  e.date_enrolled,
172
175
  e.earliest_start_date,
173
- preg_or_breast.name AS maternal_status,
174
- DATE(MIN(pregnant_or_breastfeeding.obs_datetime)) AS maternal_status_date
176
+ c.maternal_status
175
177
  FROM cdr_temp_cohort_members #{current_partition} e
176
- LEFT JOIN (
177
- SELECT max(o.obs_datetime) AS obs_datetime, o.person_id
178
- FROM obs #{current_partition} o
179
- INNER JOIN concept_name cn ON cn.concept_id = o.concept_id AND cn.name = 'CD4 count' AND cn.voided = 0
180
- INNER JOIN patient_program #{current_partition} pp ON pp.patient_id = o.person_id
181
- AND pp.program_id = #{program('HIV PROGRAM').id}
182
- AND pp.voided = 0
183
- INNER JOIN patient_state #{current_partition} ps ON ps.patient_program_id = pp.patient_program_id AND ps.voided = 0 AND ps.state = 7 AND ps.start_date <= DATE('#{end_date}')
184
- WHERE o.concept_id = #{concept_name('CD4 count').concept_id} AND o.voided = 0
185
- AND o.obs_datetime <= '#{end_date}' AND o.obs_datetime >= '#{start_date}'
186
- GROUP BY o.person_id
187
- ) current_cd4 ON current_cd4.person_id = e.patient_id
188
- LEFT JOIN obs #{current_partition} o ON o.person_id = e.patient_id AND o.concept_id = #{concept_name('CD4 count').concept_id} AND o.voided = 0 AND o.obs_datetime = current_cd4.obs_datetime
189
- LEFT JOIN obs #{current_partition} pregnant_or_breastfeeding ON pregnant_or_breastfeeding.person_id = e.patient_id
190
- AND pregnant_or_breastfeeding.concept_id IN (SELECT concept_id FROM concept_name WHERE name IN ('Breast feeding?', 'Breast feeding', 'Breastfeeding', 'Is patient pregnant?', 'patient pregnant') AND voided = 0)
191
- AND pregnant_or_breastfeeding.voided = 0
192
- AND pregnant_or_breastfeeding.value_coded = #{concept_name('Yes').concept_id}
193
- LEFT JOIN concept_name preg_or_breast ON preg_or_breast.concept_id = pregnant_or_breastfeeding.concept_id AND preg_or_breast.voided = 0
194
- WHERE e.date_enrolled <= '#{end_date}' AND e.date_enrolled >= '#{start_date}'
178
+ LEFT JOIN obs #{current_partition} current_cd4 ON current_cd4.person_id = e.patient_id AND current_cd4.concept_id = #{concept_name('CD4 count').concept_id} AND current_cd4.voided = 0
179
+ LEFT JOIN obs #{current_partition} o ON o.person_id = current_cd4.person_id AND o.concept_id = #{concept_name('CD4 count').concept_id} AND o.voided = 0 AND o.obs_datetime > current_cd4.obs_datetime
180
+ LEFT JOIN cdr_temp_maternal_status #{current_partition} c ON c.patient_id = e.patient_id
181
+ WHERE e.date_enrolled <= '#{end_date}' AND e.date_enrolled >= '#{start_date}' AND e.gender IN ('M', 'F') AND o.obs_id IS NULL
195
182
  GROUP BY e.patient_id
196
183
  SQL
197
184
  end
@@ -7,7 +7,7 @@ module MalawiHivProgramReports
7
7
  include MalawiHivProgramReports::Utils::CommonSqlQueryUtils
8
8
  include MalawiHivProgramReports::Adapters::Moh::Custom
9
9
  include MalawiHivProgramReports::Utils::ModelUtils
10
- attr_reader :start_date, :end_date, :location, :rebuild
10
+ attr_reader :start_date, :end_date, :location, :rebuild, :report
11
11
 
12
12
  def initialize(start_date:, end_date:, **kwargs)
13
13
  @start_date = ActiveRecord::Base.connection.quote(start_date.to_date.beginning_of_day.strftime('%Y-%m-%d %H:%M:%S'))
@@ -17,20 +17,16 @@ module MalawiHivProgramReports
17
17
  end
18
18
 
19
19
  def find_report
20
- if rebuild
21
- cohort = MalawiHivProgramReports::Moh::CumulativeCohort.new(start_date: start_date.to_date, end_date: end_date.to_date, definition: 'pepfar',
22
- locations: location.to_s, rebuild: true.to_s)
23
- cohort.find_report
24
- end
20
+ process_rebuild
25
21
  process_report
22
+ rescue StandardError => e
23
+ Rails.logger.error "Error running TX_RTT Report: #{e}"
24
+ Rails.logger.error e.backtrace.join("\n")
25
+ raise e
26
26
  end
27
27
 
28
28
  def data
29
- if rebuild
30
- cohort = MalawiHivProgramReports::Moh::CumulativeCohort.new(start_date: start_date.to_date, end_date: end_date.to_date, definition: 'pepfar',
31
- locations: location.to_s, rebuild: true.to_s)
32
- cohort.find_report
33
- end
29
+ process_rebuild
34
30
  process_report
35
31
  rescue StandardError => e
36
32
  Rails.logger.error "Error running TX_RTT Report: #{e}"
@@ -40,7 +36,15 @@ module MalawiHivProgramReports
40
36
 
41
37
  private
42
38
 
43
- GENDER = %w[M F].freeze
39
+ GENDER = %w[Male Female].freeze
40
+
41
+ def process_rebuild
42
+ return unless rebuild
43
+
44
+ cohort = MalawiHivProgramReports::Moh::CumulativeCohort.new(start_date: start_date.to_date, end_date: end_date.to_date, definition: 'pepfar',
45
+ locations: location.to_s, rebuild: true.to_s)
46
+ cohort.find_report
47
+ end
44
48
 
45
49
  def init_report
46
50
  pepfar_age_groups.each_with_object({}) do |age_group, age_group_report|
@@ -50,44 +54,74 @@ module MalawiHivProgramReports
50
54
  end
51
55
  end
52
56
 
57
+ def addittional_groups
58
+ @report['All'] = {}
59
+ %w[Male FP FNP FBf].each do |key|
60
+ @report['All'][key] = indicators
61
+ end
62
+ end
63
+
53
64
  def process_report
54
- report = init_report
55
- process_data report
56
- flatten_the_report report
65
+ @report = init_report
66
+ addittional_groups
67
+ process_data
68
+ flatten_the_report
57
69
  end
58
70
 
59
- def process_data(report)
71
+ def process_data
60
72
  fetch_data.each do |row|
61
73
  age_group = row['age_group']
62
74
  gender = row['gender']
63
75
  months = row['months']
64
76
  patient_id = row['patient_id']
65
77
  cd4_cat = row['cd4_count_group']
78
+ maternal_status = row['maternal_status']
66
79
 
67
80
  next unless GENDER.include?(gender)
68
81
  next unless pepfar_age_groups.include?(age_group)
69
82
 
70
- cat = report[age_group][gender]
71
- process_months(cat, months, patient_id)
72
- process_cd4(cat, months, patient_id, cd4_cat)
83
+ month_indicator = process_months(months)
84
+ cd4_indicator = process_cd4(months, cd4_cat)
85
+ process_aggreggation_rows(age_group:, gender:, month_indicator:, cd4_indicator:, maternal_status:,
86
+ patient_id:)
73
87
  end
74
88
  end
75
89
 
76
- def process_months(report, months, patient_id)
77
- return report[:returned_less_than_3_months] << patient_id if months.blank?
78
- return report[:returned_less_than_3_months] << patient_id if months < 3
79
- return report[:returned_greater_than_3_months_and_less_than_6_months] << patient_id if months >= 3 && months < 6
90
+ def process_aggreggation_rows(age_group:, gender:, month_indicator:, cd4_indicator:, **kwargs)
91
+ @report[age_group][gender][month_indicator] << kwargs[:patient_id] unless month_indicator&.blank?
92
+ @report[age_group][gender][cd4_indicator] << kwargs[:patient_id] unless cd4_indicator&.blank?
80
93
 
81
- report[:returned_greater_than_or_equal_to_6_months] << patient_id if months >= 6
82
- end
83
-
84
- def process_cd4(report, months, patient_id, cd4_cat)
85
- if cd4_cat == 'unknown_cd4_count' && (months.blank? || months <= 2)
86
- report[:not_eligible_for_cd4] << patient_id
94
+ if gender == 'Male'
95
+ @report['All']['Male'][month_indicator] << kwargs[:patient_id] unless month_indicator&.blank?
96
+ @report['All']['Male'][cd4_indicator] << kwargs[:patient_id] unless cd4_indicator&.blank?
87
97
  return
88
98
  end
89
99
 
90
- report[cd4_cat.to_sym] << patient_id
100
+ case kwargs[:maternal_status]
101
+ when 'FP'
102
+ @report['All']['FP'][month_indicator] << kwargs[:patient_id] unless month_indicator&.blank?
103
+ @report['All']['FP'][month_indicator] << kwargs[:patient_id] unless cd4_indicator&.blank?
104
+ when 'FBf'
105
+ @report['All']['FBf'][month_indicator] << kwargs[:patient_id] unless month_indicator&.blank?
106
+ @report['All']['FBf'][cd4_indicator] << kwargs[:patient_id] unless cd4_indicator&.blank?
107
+ else
108
+ @report['All']['FNP'][month_indicator] << kwargs[:patient_id] unless month_indicator&.blank?
109
+ @report['All']['FNP'][cd4_indicator] << kwargs[:patient_id] unless cd4_indicator&.blank?
110
+ end
111
+ end
112
+
113
+ def process_months(months)
114
+ return :returned_less_than_3_months if months.blank?
115
+ return :returned_less_than_3_months if months < 3
116
+ return :returned_greater_than_3_months_and_less_than_6_months if months >= 3 && months < 6
117
+
118
+ :returned_greater_than_or_equal_to_6_months if months >= 6
119
+ end
120
+
121
+ def process_cd4(months, cd4_cat)
122
+ cd4_cat == 'unknown_cd4_count' if months.blank? || months <= 2
123
+
124
+ cd4_cat.to_sym
91
125
  end
92
126
 
93
127
  def indicators
@@ -106,29 +140,32 @@ module MalawiHivProgramReports
106
140
  {
107
141
  age_group:,
108
142
  gender:,
109
- cd4_less_than_200: age_group_report[:cd4_less_than_200],
110
- cd4_greater_than_or_equal_to_200: age_group_report[:cd4_greater_than_or_equal_to_200],
111
- unknown_cd4_count: age_group_report[:unknown_cd4_count],
112
- not_eligible_for_cd4: age_group_report[:not_eligible_for_cd4],
113
- returned_less_than_3_months: age_group_report[:returned_less_than_3_months],
114
- returned_greater_than_3_months_and_less_than_6_months: age_group_report[:returned_greater_than_3_months_and_less_than_6_months],
115
- returned_greater_than_or_equal_to_6_months: age_group_report[:returned_greater_than_or_equal_to_6_months]
143
+ **age_group_report
116
144
  }
117
145
  end
118
146
 
119
- def flatten_the_report(report)
147
+ def flatten_the_report
120
148
  result = []
121
- report.each do |age_group, age_group_report|
122
- result << process_age_group_report(age_group, 'M', age_group_report['M'])
123
- result << process_age_group_report(age_group, 'F', age_group_report['F'])
149
+ @report.each do |age_group, age_group_report|
150
+ next if age_group == 'Unknown'
151
+
152
+ age_group_report.each_key do |gender|
153
+ next if gender == 'Unknown'
154
+
155
+ result << process_age_group_report(age_group, gender, age_group_report[gender])
156
+ end
124
157
  end
125
- sorted_results = result.sort_by do |item|
126
- gender_score = item[:gender] == 'Female' ? 0 : 1
127
- age_group_score = pepfar_age_groups.index(item[:age_group])
158
+
159
+ new_group = pepfar_age_groups.map { |age_group| age_group }
160
+ new_group << 'All'
161
+ gender_scores = { 'Female' => 0, 'Male' => 1, 'FNP' => 3, 'FP' => 2, 'FBf' => 4 }
162
+ result_scores = result.sort_by do |item|
163
+ gender_score = gender_scores[item[:gender]] || 999
164
+ age_group_score = new_group.index(item[:age_group]) || 999
128
165
  [gender_score, age_group_score]
129
166
  end
130
- # sort by gender, start all females and push all males to the end
131
- sorted_results.sort_by { |h| [h[:gender] == 'F' ? 0 : 1] }
167
+ # remove all unknown age groups
168
+ result_scores.reject { |item| item[:age_group].match?(/unknown/i) }
132
169
  end
133
170
 
134
171
  def fetch_data
@@ -136,7 +173,12 @@ module MalawiHivProgramReports
136
173
  SELECT
137
174
  e.patient_id,
138
175
  disaggregated_age_group(e.birthdate, #{end_date}) AS age_group,
139
- e.gender,
176
+ CASE e.gender
177
+ WHEN 'M' THEN 'Male'
178
+ WHEN 'F' THEN 'Female'
179
+ ELSE 'Unknown'
180
+ END gender,
181
+ ms.maternal_status,
140
182
  s.cum_outcome initial_outcome,
141
183
  o.cum_outcome final_outcome,
142
184
  TIMESTAMPDIFF(MONTH, COALESCE(s.outcome_date, c.outcome_date), ord.min_order_date) months,
@@ -153,7 +195,9 @@ module MalawiHivProgramReports
153
195
  INNER JOIN cdr_temp_patient_outcomes_start #{current_partition} s ON s.patient_id = e.patient_id AND s.cum_outcome IN ('Defaulted', 'Treatment stopped')
154
196
  INNER JOIN cdr_temp_current_state_start #{current_partition} c ON c.patient_id = e.patient_id
155
197
  INNER JOIN cdr_temp_max_drug_orders #{current_partition} ord ON ord.patient_id = e.patient_id
198
+ LEFT JOIN cdr_temp_maternal_status #{current_partition} ms ON ms.patient_id = e.patient_id
156
199
  LEFT JOIN obs #{current_partition} cd4_result ON cd4_result.person_id = e.patient_id AND cd4_result.concept_id = #{concept_name('CD4 count').concept_id} AND cd4_result.voided = 0
200
+ WHERE e.gender IN ('M', 'F')
157
201
  GROUP BY e.patient_id
158
202
  SQL
159
203
  end