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.
- checksums.yaml +4 -4
- data/app/services/malawi_hiv_program_reports/cohort/disaggregated.rb +57 -47
- data/app/services/malawi_hiv_program_reports/moh/cumulative_cohort.rb +62 -1
- data/app/services/malawi_hiv_program_reports/pepfar/maternal_status.rb +103 -1
- data/app/services/malawi_hiv_program_reports/pepfar/tb_prev3.rb +214 -172
- data/app/services/malawi_hiv_program_reports/pepfar/tx_curr_mmd.rb +63 -25
- data/app/services/malawi_hiv_program_reports/pepfar/tx_ml.rb +137 -41
- data/app/services/malawi_hiv_program_reports/pepfar/tx_new.rb +51 -64
- data/app/services/malawi_hiv_program_reports/pepfar/tx_rtt.rb +91 -47
- data/app/services/malawi_hiv_program_reports/pepfar/tx_tb.rb +188 -135
- data/app/services/malawi_hiv_program_reports/report_map.rb +1 -1
- data/lib/malawi_hiv_program_reports/version.rb +1 -1
- metadata +3 -3
@@ -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
|
-
|
22
|
-
|
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 =
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
-
|
67
|
-
|
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
|
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
|
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[
|
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
|
-
|
89
|
-
|
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:,
|
94
|
+
def process_aggreggation_rows(report:, gender:, indicator:, **kwargs)
|
100
95
|
maternal_status = kwargs[:maternal_status]
|
101
|
-
|
96
|
+
age_group = kwargs[:age_group]
|
97
|
+
report[age_group][gender][indicator.to_sym] << kwargs[:patient_id]
|
102
98
|
|
103
|
-
if gender == '
|
99
|
+
if gender == 'Male'
|
104
100
|
report['All']['Male'][indicator.to_sym] << kwargs[:patient_id]
|
105
|
-
|
101
|
+
return
|
102
|
+
end
|
103
|
+
|
104
|
+
case maternal_status
|
105
|
+
when 'FP'
|
106
106
|
report['All']['FP'][indicator.to_sym] << kwargs[:patient_id]
|
107
|
-
|
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
|
120
|
-
|
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
|
-
|
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
|
-
|
178
|
-
|
179
|
-
|
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
|
-
|
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
|
-
|
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[
|
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
|
-
|
56
|
-
|
65
|
+
@report = init_report
|
66
|
+
addittional_groups
|
67
|
+
process_data
|
68
|
+
flatten_the_report
|
57
69
|
end
|
58
70
|
|
59
|
-
def process_data
|
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
|
-
|
71
|
-
|
72
|
-
|
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
|
77
|
-
|
78
|
-
|
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
|
-
|
82
|
-
|
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
|
-
|
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
|
-
|
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
|
147
|
+
def flatten_the_report
|
120
148
|
result = []
|
121
|
-
report.each do |age_group, age_group_report|
|
122
|
-
|
123
|
-
|
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
|
-
|
126
|
-
|
127
|
-
|
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
|
-
#
|
131
|
-
|
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
|