malawi_hiv_program_reports 1.0.1 → 1.0.2
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/README.md +16 -0
- data/app/services/malawi_hiv_program_reports/adapters/moh/custom.rb +199 -0
- data/app/services/malawi_hiv_program_reports/archiving_candidates.rb +130 -0
- data/app/services/malawi_hiv_program_reports/arv_refill_periods.rb +311 -0
- data/app/services/malawi_hiv_program_reports/clinic/README.md +5 -0
- data/app/services/malawi_hiv_program_reports/clinic/appointments_report.rb +317 -0
- data/app/services/malawi_hiv_program_reports/clinic/discrepancy_report.rb +42 -0
- data/app/services/malawi_hiv_program_reports/clinic/docs/hypertension_report.md +31 -0
- data/app/services/malawi_hiv_program_reports/clinic/drug_dispensations.rb +48 -0
- data/app/services/malawi_hiv_program_reports/clinic/external_consultation_clients.rb +69 -0
- data/app/services/malawi_hiv_program_reports/clinic/hypertension_report.rb +223 -0
- data/app/services/malawi_hiv_program_reports/clinic/ipt_coverage.rb +112 -0
- data/app/services/malawi_hiv_program_reports/clinic/ipt_report.rb +69 -0
- data/app/services/malawi_hiv_program_reports/clinic/lims_results.rb +55 -0
- data/app/services/malawi_hiv_program_reports/clinic/outcome_list.rb +127 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_alive_and_on_treatment.rb +57 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_due_for_viral_load.rb +39 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_on_antiretrovirals.rb +44 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_on_dtg.rb +36 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_on_treatment.rb +42 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_with_outdated_demographics.rb +173 -0
- data/app/services/malawi_hiv_program_reports/clinic/pregnant_patients.rb +91 -0
- data/app/services/malawi_hiv_program_reports/clinic/regimen_dispensation_data.rb +282 -0
- data/app/services/malawi_hiv_program_reports/clinic/regimen_switch.rb +456 -0
- data/app/services/malawi_hiv_program_reports/clinic/regimens_and_formulations.rb +182 -0
- data/app/services/malawi_hiv_program_reports/clinic/regimens_by_weight_and_gender.rb +108 -0
- data/app/services/malawi_hiv_program_reports/clinic/retention.rb +246 -0
- data/app/services/malawi_hiv_program_reports/clinic/stock_card_report.rb +65 -0
- data/app/services/malawi_hiv_program_reports/clinic/tpt_outcome.rb +494 -0
- data/app/services/malawi_hiv_program_reports/clinic/tx_rtt.rb +169 -0
- data/app/services/malawi_hiv_program_reports/clinic/viral_load.rb +292 -0
- data/app/services/malawi_hiv_program_reports/clinic/viral_load_disaggregated.rb +97 -0
- data/app/services/malawi_hiv_program_reports/clinic/viral_load_results.rb +175 -0
- data/app/services/malawi_hiv_program_reports/clinic/visits_report.rb +113 -0
- data/app/services/malawi_hiv_program_reports/clinic/vl_collection.rb +48 -0
- data/app/services/malawi_hiv_program_reports/cohort/outcomes.rb +338 -0
- data/app/services/malawi_hiv_program_reports/cohort/regimens.rb +69 -0
- data/app/services/malawi_hiv_program_reports/cohort/side_effects.rb +141 -0
- data/app/services/malawi_hiv_program_reports/cohort/tpt.rb +172 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort.rb +278 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_builder.rb +2340 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated.rb +608 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated_additions.rb +208 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated_builder.rb +526 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_struct.rb +219 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_survival_analysis.rb +203 -0
- data/app/services/malawi_hiv_program_reports/moh/moh_tpt.rb +223 -0
- data/app/services/malawi_hiv_program_reports/moh/tpt_newly_initiated.rb +235 -0
- data/app/services/malawi_hiv_program_reports/pepfar/defaulter_list.rb +25 -0
- data/app/services/malawi_hiv_program_reports/pepfar/maternal_status.rb +29 -0
- data/app/services/malawi_hiv_program_reports/pepfar/patient_start_vl.rb +45 -0
- data/app/services/malawi_hiv_program_reports/pepfar/regimen_switch.rb +479 -0
- data/app/services/malawi_hiv_program_reports/pepfar/sc_arvdisp.rb +174 -0
- data/app/services/malawi_hiv_program_reports/pepfar/sc_curr.rb +98 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tb_prev.rb +163 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tb_prev2.rb +222 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tb_prev3.rb +421 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tpt_status.rb +181 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tx_ml.rb +181 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tx_new.rb +202 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tx_rtt.rb +288 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tx_tb.rb +283 -0
- data/app/services/malawi_hiv_program_reports/pepfar/utils.rb +141 -0
- data/app/services/malawi_hiv_program_reports/pepfar/viral_load_coverage.rb +414 -0
- data/app/services/malawi_hiv_program_reports/pepfar/viral_load_coverage2.rb +433 -0
- data/app/services/malawi_hiv_program_reports/report_map.rb +56 -0
- data/app/services/malawi_hiv_program_reports/utils/README.md +8 -0
- data/app/services/malawi_hiv_program_reports/utils/common_sql_query_utils.rb +60 -0
- data/app/services/malawi_hiv_program_reports/utils/concurrency_utils.rb +53 -0
- data/app/services/malawi_hiv_program_reports/utils/docs/common_sql_query_utils.md +53 -0
- data/app/services/malawi_hiv_program_reports/utils/model_utils.rb +66 -0
- data/app/services/malawi_hiv_program_reports/utils/parameter_utils.rb +32 -0
- data/app/services/malawi_hiv_program_reports/utils/time_utils.rb +52 -0
- data/lib/malawi_hiv_program_reports/version.rb +1 -1
- metadata +74 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MalawiHivProgramReports
|
|
4
|
+
module Moh
|
|
5
|
+
# This class is used to add additional cohort disaggregated data
|
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
|
7
|
+
class CohortDisaggregatedAdditions
|
|
8
|
+
COHORT_REGIMENS = %w[
|
|
9
|
+
0P 2P 4PP 4PA 9PP 9PA 11PP 11PA 12PP 12PA 14PP 14PA 15PP 15PA 16P 17PP 17PA
|
|
10
|
+
4A 5A 6A 7A 8A 9A 10A 11A 12A 13A 14A 15A 16A 17A
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
def initialize(start_date:, end_date:, gender:, age_group:)
|
|
14
|
+
@start_date = start_date
|
|
15
|
+
@end_date = end_date
|
|
16
|
+
@gender = gender
|
|
17
|
+
@age_group = age_group
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def screened_for_tb
|
|
21
|
+
return screened_for_tb_female_client('FP') if @gender == 'pregnant'
|
|
22
|
+
return screened_for_tb_female_client('FNP') if @gender == 'fnp'
|
|
23
|
+
return screened_for_tb_female_client('FBf') if @gender == 'breastfeeding'
|
|
24
|
+
|
|
25
|
+
gender = @gender.first.upcase
|
|
26
|
+
results = ActiveRecord::Base.connection.select_all <<~SQL
|
|
27
|
+
SELECT
|
|
28
|
+
e.patient_id, disaggregated_age_group(e.birthdate, DATE('#{@end_date}')) age_group
|
|
29
|
+
FROM temp_earliest_start_date e
|
|
30
|
+
INNER JOIN temp_patient_outcomes USING(patient_id)
|
|
31
|
+
WHERE cum_outcome = 'On antiretrovirals' AND LEFT(gender,1) = '#{gender}'
|
|
32
|
+
GROUP BY e.patient_id HAVING age_group = '#{@age_group}';
|
|
33
|
+
SQL
|
|
34
|
+
|
|
35
|
+
patient_ids = []
|
|
36
|
+
(results || []).each do |r|
|
|
37
|
+
patient_ids << r['patient_id'].to_i
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
tb_screened(patient_ids)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def clients_given_ipt
|
|
44
|
+
return female_clients_given_ipt('FP') if @gender == 'pregnant'
|
|
45
|
+
return female_clients_given_ipt('FNP') if @gender == 'fnp'
|
|
46
|
+
return female_clients_given_ipt('FBf') if @gender == 'breastfeeding'
|
|
47
|
+
|
|
48
|
+
gender = @gender.first.upcase
|
|
49
|
+
|
|
50
|
+
patient_ids = []
|
|
51
|
+
results = ActiveRecord::Base.connection.select_all <<~SQL
|
|
52
|
+
SELECT
|
|
53
|
+
e.patient_id, disaggregated_age_group(e.birthdate, DATE('#{@end_date}')) age_group
|
|
54
|
+
FROM temp_earliest_start_date e
|
|
55
|
+
INNER JOIN temp_patient_outcomes USING(patient_id)
|
|
56
|
+
WHERE cum_outcome = 'On antiretrovirals' AND LEFT(gender,1) = '#{gender}'
|
|
57
|
+
GROUP BY e.patient_id HAVING age_group = '#{@age_group}';
|
|
58
|
+
SQL
|
|
59
|
+
|
|
60
|
+
(results || []).each do |row|
|
|
61
|
+
patient_ids << row['patient_id'].to_i
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return [] if patient_ids.blank?
|
|
65
|
+
|
|
66
|
+
given_ipt(patient_ids)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def disaggregated_regimen_distribution
|
|
70
|
+
additional_sql = ''
|
|
71
|
+
additional_for_women_sql = ''
|
|
72
|
+
gender = @gender.first.upcase
|
|
73
|
+
|
|
74
|
+
if @age_group == 'All'
|
|
75
|
+
case @gender.upcase
|
|
76
|
+
when 'FP'
|
|
77
|
+
additional_for_women_sql = 'INNER JOIN temp_disaggregated t ON t.patient_id = e.patient_id'
|
|
78
|
+
additional_for_women_sql += " AND t.maternal_status = 'FP' "
|
|
79
|
+
when 'FBF'
|
|
80
|
+
additional_for_women_sql = 'INNER JOIN temp_disaggregated t ON t.patient_id = e.patient_id'
|
|
81
|
+
additional_for_women_sql += " AND t.maternal_status = 'Fbf' "
|
|
82
|
+
when 'FNP'
|
|
83
|
+
additional_for_women_sql = 'INNER JOIN temp_disaggregated t ON t.patient_id = e.patient_id'
|
|
84
|
+
additional_for_women_sql += " AND t.maternal_status = 'FNP' "
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
additional_sql = "HAVING age_group = '#{@age_group}'"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
patients = ActiveRecord::Base.connection.select_all <<~SQL
|
|
91
|
+
SELECT
|
|
92
|
+
e.patient_id, disaggregated_age_group(e.birthdate, DATE("#{@end_date.to_date}")) age_group
|
|
93
|
+
FROM temp_earliest_start_date e
|
|
94
|
+
INNER JOIN temp_patient_outcomes o ON o.patient_id = e.patient_id
|
|
95
|
+
#{additional_for_women_sql}
|
|
96
|
+
WHERE LEFT(gender,1) = '#{gender}' AND o.cum_outcome = 'On antiretrovirals'
|
|
97
|
+
AND DATE(date_enrolled) <= '#{@end_date.to_date}'
|
|
98
|
+
GROUP BY e.patient_id #{additional_sql};
|
|
99
|
+
SQL
|
|
100
|
+
|
|
101
|
+
return {} if patients.blank?
|
|
102
|
+
|
|
103
|
+
patient_ids = patients.map { |p| p['patient_id'].to_i }
|
|
104
|
+
data = {}
|
|
105
|
+
|
|
106
|
+
patient_ids.each do |patient_id|
|
|
107
|
+
regimen_data = ActiveRecord::Base.connection.select_one <<~SQL
|
|
108
|
+
SELECT patient_current_regimen(#{patient_id}, DATE('#{@end_date.to_date}')) regimen;
|
|
109
|
+
SQL
|
|
110
|
+
|
|
111
|
+
regimen = (COHORT_REGIMENS.include? regimen_data['regimen']) ? regimen_data['regimen'] : 'N/A'
|
|
112
|
+
data[regimen] = [] if data[regimen].blank?
|
|
113
|
+
data[regimen] << patient_id
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
data
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
def given_ipt(patient_ids)
|
|
122
|
+
return [] if patient_ids.blank?
|
|
123
|
+
|
|
124
|
+
isoniazid_concept_id = ::ConceptName.find_by(name: 'Isoniazid').concept_id
|
|
125
|
+
isoniazid_rifapentine_concept_id = ::ConceptName.find_by(name: 'Isoniazid/Rifapentine').concept_id
|
|
126
|
+
pyridoxine_concept_id = ::ConceptName.find_by(name: 'Pyridoxine').concept_id
|
|
127
|
+
|
|
128
|
+
results = ActiveRecord::Base.connection.select_all(
|
|
129
|
+
"SELECT ods.patient_id FROM orders ods
|
|
130
|
+
INNER JOIN drug_order dos ON ods.order_id = dos.order_id AND ods.voided = 0
|
|
131
|
+
WHERE ods.concept_id IN (#{isoniazid_concept_id}, #{pyridoxine_concept_id}, #{isoniazid_rifapentine_concept_id})
|
|
132
|
+
AND dos.quantity IS NOT NULL
|
|
133
|
+
AND ods.patient_id in (#{patient_ids.join(',')})
|
|
134
|
+
AND ods.start_date BETWEEN '#{@start_date.to_date.strftime('%Y-%m-%d 00:00:00')}'
|
|
135
|
+
AND '#{@end_date.to_date.strftime('%Y-%m-%d 23:59:59')}'
|
|
136
|
+
AND DATE(ods.start_date) = (SELECT MAX(DATE(o.start_date)) FROM orders o
|
|
137
|
+
INNER JOIN drug_order d ON o.order_id = d.order_id AND o.voided = 0
|
|
138
|
+
WHERE o.concept_id IN (#{isoniazid_concept_id}, #{pyridoxine_concept_id}, #{isoniazid_rifapentine_concept_id})
|
|
139
|
+
AND o.patient_id = ods.patient_id
|
|
140
|
+
AND d.quantity IS NOT NULL
|
|
141
|
+
AND o.start_date BETWEEN '#{@start_date.to_date.strftime('%Y-%m-%d 00:00:00')}'
|
|
142
|
+
AND '#{@end_date.to_date.strftime('%Y-%m-%d 23:59:59')}')
|
|
143
|
+
GROUP BY ods.patient_id;"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
results_patients = []
|
|
147
|
+
|
|
148
|
+
(results || []).each do |row|
|
|
149
|
+
results_patients << row['patient_id'].to_i
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
results_patients
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def tb_screened(patient_ids)
|
|
156
|
+
return [] if patient_ids.blank?
|
|
157
|
+
|
|
158
|
+
results = ActiveRecord::Base.connection.select_all <<~SQL
|
|
159
|
+
SELECT e.*, tb_status FROM temp_earliest_start_date e
|
|
160
|
+
INNER JOIN temp_patient_tb_status s ON s.patient_id = e.patient_id
|
|
161
|
+
INNER JOIN temp_patient_outcomes o ON o.patient_id = e.patient_id
|
|
162
|
+
WHERE o.cum_outcome = 'On antiretrovirals' AND e.patient_id IN(#{patient_ids.join(',')})
|
|
163
|
+
AND DATE(e.date_enrolled) <= '#{@end_date.to_date}';
|
|
164
|
+
SQL
|
|
165
|
+
|
|
166
|
+
patient_ids = []
|
|
167
|
+
(results || []).each do |r|
|
|
168
|
+
patient_ids << r['patient_id'].to_i unless r['tb_status'].blank?
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
patient_ids
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def screened_for_tb_female_client(group)
|
|
175
|
+
results = ActiveRecord::Base.connection.select_all <<~SQL
|
|
176
|
+
SELECT f.patient_id FROM temp_disaggregated f
|
|
177
|
+
INNER JOIN temp_patient_outcomes o ON o.patient_id = f.patient_id
|
|
178
|
+
WHERE maternal_status = "#{group}"
|
|
179
|
+
AND o.cum_outcome = 'On antiretrovirals' GROUP BY f.patient_id;
|
|
180
|
+
SQL
|
|
181
|
+
|
|
182
|
+
patient_ids = []
|
|
183
|
+
(results || []).each do |r|
|
|
184
|
+
patient_ids << r['patient_id'].to_i
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
tb_screened(patient_ids)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def female_clients_given_ipt(group)
|
|
191
|
+
results = ActiveRecord::Base.connection.select_all <<~SQL
|
|
192
|
+
SELECT f.patient_id FROM temp_disaggregated f
|
|
193
|
+
INNER JOIN temp_patient_outcomes o ON o.patient_id = f.patient_id
|
|
194
|
+
WHERE maternal_status = "#{group}"
|
|
195
|
+
AND o.cum_outcome = 'On antiretrovirals' GROUP BY f.patient_id;
|
|
196
|
+
SQL
|
|
197
|
+
|
|
198
|
+
patient_ids = []
|
|
199
|
+
(results || []).each do |r|
|
|
200
|
+
patient_ids << r['patient_id'].to_i
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
given_ipt(patient_ids)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
# rubocop:enable Metrics/ClassLength
|
|
207
|
+
end
|
|
208
|
+
end
|