malawi_hiv_program_reports 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,526 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MalawiHivProgramReports
|
4
|
+
module Moh
|
5
|
+
# This class is used to add additional cohort disaggregated data
|
6
|
+
class CohortDisaggregatedBuilder < CohortBuilder
|
7
|
+
def initialize(outcomes_definition: 'moh', **kwargs)
|
8
|
+
unless %w[moh pepfar].include?(outcomes_definition.downcase)
|
9
|
+
raise ::ArgumentError, "Invalid outcomes_definition `#{outcomes_definition}` expected moh or pepfar"
|
10
|
+
end
|
11
|
+
|
12
|
+
@location = kwargs[:location]
|
13
|
+
@adapter = ActiveRecord::Base.connection.adapter_name.downcase
|
14
|
+
@outcomes_definition = outcomes_definition
|
15
|
+
end
|
16
|
+
|
17
|
+
def build(_cohort_struct, start_date, end_date)
|
18
|
+
build_disaggregated_report(cohort(nil, start_date, end_date), start_date, end_date)
|
19
|
+
rescue StandardError => e
|
20
|
+
Rails.logger.error "Error Message #{e.message}"
|
21
|
+
raise e
|
22
|
+
end
|
23
|
+
|
24
|
+
def cohort(_cohort_struct, start_date, end_date)
|
25
|
+
time_started = Time.now.strftime('%Y-%m-%d %H:%M:%S')
|
26
|
+
|
27
|
+
@cohort_struct = cohort_struct = CohortStruct.new
|
28
|
+
|
29
|
+
#=end
|
30
|
+
# Get earliest date enrolled
|
31
|
+
@cohort_cum_start_date = cum_start_date = get_cum_start_date
|
32
|
+
|
33
|
+
# Total registered
|
34
|
+
cohort_struct.total_registered = total_registered(start_date, end_date)
|
35
|
+
cohort_struct.cum_total_registered = total_registered(cum_start_date, end_date)
|
36
|
+
|
37
|
+
# Patients initiated on ART first time
|
38
|
+
cohort_struct.initiated_on_art_first_time = initiated_on_art_first_time(start_date, end_date)
|
39
|
+
cohort_struct.cum_initiated_on_art_first_time = initiated_on_art_first_time(cum_start_date, end_date)
|
40
|
+
|
41
|
+
# Patients re-initiated on ART
|
42
|
+
cohort_struct.re_initiated_on_art = re_initiated_on_art(start_date, end_date)
|
43
|
+
cohort_struct.cum_re_initiated_on_art = re_initiated_on_art(cum_start_date, end_date)
|
44
|
+
|
45
|
+
# Patients transferred in on ART
|
46
|
+
cohort_struct.transfer_in = transfer_in(start_date, end_date, cohort_struct.re_initiated_on_art)
|
47
|
+
cohort_struct.cum_transfer_in = transfer_in(cum_start_date, end_date, cohort_struct.cum_re_initiated_on_art)
|
48
|
+
|
49
|
+
# All males
|
50
|
+
cohort_struct.all_males = males(start_date, end_date)
|
51
|
+
cohort_struct.cum_all_males = males(cum_start_date, end_date)
|
52
|
+
|
53
|
+
# Unknown age
|
54
|
+
cohort_struct.unknown_age = unknown_age(start_date, end_date)
|
55
|
+
cohort_struct.cum_unknown_age = unknown_age(cum_start_date, end_date)
|
56
|
+
|
57
|
+
# No TB
|
58
|
+
# total_registered - (current_episode - tb_within_the_last_two_years)
|
59
|
+
cohort_struct.no_tb = no_tb(cohort_struct.total_registered, cohort_struct.tb_within_the_last_two_years,
|
60
|
+
cohort_struct.current_episode_of_tb)
|
61
|
+
cohort_struct.cum_no_tb = cum_no_tb(cohort_struct.cum_total_registered,
|
62
|
+
cohort_struct.cum_tb_within_the_last_two_years, cohort_struct.cum_current_episode_of_tb)
|
63
|
+
|
64
|
+
# Total Alive and On ART
|
65
|
+
# Unique PatientProgram entries at the current location for those patients with at least one state
|
66
|
+
# ON ARVs and earliest start date of the 'ON ARVs' state less than or equal to end date of quarter
|
67
|
+
# and latest state is ON ARVs (Excluding defaulters)
|
68
|
+
cohort_struct.total_alive_and_on_art = get_outcome('On antiretrovirals')
|
69
|
+
|
70
|
+
# Pregnant women
|
71
|
+
#
|
72
|
+
# Unique PatientProgram entries at the current location for those patients with at least one state ON ARVs
|
73
|
+
# and earliest start date of the 'ON ARVs' state within the quarter
|
74
|
+
# and having a REASON FOR ELIGIBILITY observation with an answer as PATIENT PREGNANT
|
75
|
+
cohort_struct.total_pregnant_women = total_pregnant_women(cohort_struct.total_alive_and_on_art, cum_start_date,
|
76
|
+
end_date)
|
77
|
+
|
78
|
+
# Breastfeeding mothers
|
79
|
+
#
|
80
|
+
# Unique PatientProgram entries at the current location for those patients with at least one state
|
81
|
+
# ON ARVs and earliest start date of the 'ON ARVs' state within the quarter
|
82
|
+
# and having a REASON FOR ELIGIBILITY observation with an answer as BREASTFEEDING
|
83
|
+
cohort_struct.total_breastfeeding_women = total_breastfeeding_women(cohort_struct.total_alive_and_on_art, cohort_struct.total_pregnant_women,
|
84
|
+
cum_start_date, end_date)
|
85
|
+
|
86
|
+
# Non-pregnant females (all ages)
|
87
|
+
|
88
|
+
# Unique PatientProgram entries at the current location for those patients with at least one state ON ARVs
|
89
|
+
# and earliest start date of the 'ON ARVs' state within the quarter and having gender of
|
90
|
+
# related PERSON entry as F for female and no entries of 'IS PATIENT PREGNANT?' observation answered 'YES'
|
91
|
+
# in related HIV CLINIC CONSULTATION encounters not within 28 days from earliest registration date
|
92
|
+
pregnant_females = []
|
93
|
+
(cohort_struct.total_pregnant_women || []).each do |patient|
|
94
|
+
pregnant_females << patient['person_id'].to_i
|
95
|
+
end
|
96
|
+
cohort_struct.non_pregnant_females = non_pregnant_females(start_date, end_date, pregnant_females)
|
97
|
+
cohort_struct.cum_non_pregnant_females = non_pregnant_females(cum_start_date, end_date, pregnant_females)
|
98
|
+
end_time = Time.now.strftime('%Y-%m-%d %H:%M:%S')
|
99
|
+
|
100
|
+
puts "Started at: #{time_started}. Finished at: #{end_time}. Total time in minutes: #{((end_time.to_time - time_started.to_time) / 60).round(2)} minutes."
|
101
|
+
Rails.logger.info "Started at: #{time_started}. Finished at: #{end_time}. Total time in minutes: #{((end_time.to_time - time_started.to_time) / 60).round(2)} minutes."
|
102
|
+
cohort_struct
|
103
|
+
rescue StandardError => e
|
104
|
+
Rails.logger.error "Error Message #{e}"
|
105
|
+
raise e
|
106
|
+
end
|
107
|
+
|
108
|
+
def build_disaggregated_report(cohort, start_date, end_date)
|
109
|
+
@age_groups = ['0-5 months', '6-11 months', '12-23 months', '2-4 years',
|
110
|
+
'5-9 years', '10-14 years', '15-17 years', '18-19 years',
|
111
|
+
'20-24 years', '25-29 years', '30-34 years', '35-39 years',
|
112
|
+
'40-44 years', '45-49 years', '50+ years', 'All']
|
113
|
+
|
114
|
+
report = {}
|
115
|
+
counter = 1
|
116
|
+
|
117
|
+
%w[Male Female].each do |gender|
|
118
|
+
@age_groups.each do |ag|
|
119
|
+
next if /all/i.match?(ag)
|
120
|
+
|
121
|
+
report[counter] = {} if report[counter].blank?
|
122
|
+
report[counter][gender] = {} if report[counter][gender].blank?
|
123
|
+
report[counter][gender][ag] = get_data(cohort, start_date, end_date, gender, ag)
|
124
|
+
counter += 1
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
%w[M FP FNP FBf].each do |gender|
|
129
|
+
@age_groups.each do |ag|
|
130
|
+
next unless /all/i.match?(ag)
|
131
|
+
|
132
|
+
report[counter] = {} if report[counter].blank?
|
133
|
+
report[counter][gender] = {} if report[counter][gender].blank?
|
134
|
+
report[counter][gender][ag] = get_data(cohort, start_date, end_date, gender, ag)
|
135
|
+
counter += 1
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
report
|
140
|
+
rescue StandardError => e
|
141
|
+
Rails.logger.error "Error Message #{e}"
|
142
|
+
raise e
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_data(cohort, start_date, end_date, gender, age_group)
|
146
|
+
@cohort = cohort
|
147
|
+
|
148
|
+
if %w[Male Female].include?(gender)
|
149
|
+
case age_group
|
150
|
+
when '50+ years'
|
151
|
+
yrs_months = 'year'
|
152
|
+
age_to = 1000
|
153
|
+
age_from = 50
|
154
|
+
when /years/i
|
155
|
+
age_from, age_to = age_group.sub(' years', '').split('-')
|
156
|
+
yrs_months = 'year'
|
157
|
+
when /months/i
|
158
|
+
age_from, age_to = age_group.sub(' months', '').split('-')
|
159
|
+
yrs_months = 'month'
|
160
|
+
end
|
161
|
+
|
162
|
+
g = gender.first
|
163
|
+
|
164
|
+
started_on_art = get_started_on_art(yrs_months, age_from, age_to, g, start_date, end_date)
|
165
|
+
alive_on_art = get_alive_on_art(yrs_months, age_from, age_to, g, @cohort_cum_start_date, end_date)
|
166
|
+
started_on_ipt = get_started_on_ipt(yrs_months, age_from, age_to, g, @cohort_cum_start_date, end_date)
|
167
|
+
screened_for_tb = get_screened_for_tb(yrs_months, age_from, age_to, g, @cohort_cum_start_date, end_date)
|
168
|
+
|
169
|
+
return [started_on_art&.length || 0,
|
170
|
+
alive_on_art&.length || 0,
|
171
|
+
started_on_ipt&.length || 0,
|
172
|
+
screened_for_tb&.length || 0]
|
173
|
+
end
|
174
|
+
|
175
|
+
if gender == 'M'
|
176
|
+
age_from = 0
|
177
|
+
age_to = 1000
|
178
|
+
yrs_months = 'year'
|
179
|
+
started_on_art = get_started_on_art(yrs_months, age_from, age_to, gender, start_date, end_date)
|
180
|
+
alive_on_art = get_alive_on_art(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date)
|
181
|
+
started_on_ipt = get_started_on_ipt(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date)
|
182
|
+
screened_for_tb = get_screened_for_tb(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date)
|
183
|
+
|
184
|
+
return [started_on_art&.length || 0,
|
185
|
+
alive_on_art&.length || 0,
|
186
|
+
started_on_ipt&.length || 0,
|
187
|
+
screened_for_tb&.length || 0]
|
188
|
+
end
|
189
|
+
|
190
|
+
if gender == 'FP'
|
191
|
+
a, b, c, d = get_fp(start_date, end_date)
|
192
|
+
return [a.length, b.length, c.length, d.length]
|
193
|
+
end
|
194
|
+
|
195
|
+
if gender == 'FNP'
|
196
|
+
fnp_a, fnp_b, fnp_c, fnp_d = get_fnp(start_date, end_date)
|
197
|
+
return [fnp_a.length, fnp_b.length, fnp_c.length, fnp_d.length]
|
198
|
+
end
|
199
|
+
|
200
|
+
if gender == 'FBf'
|
201
|
+
a, b, c, d = get_fbf(start_date, end_date)
|
202
|
+
return [a.length, b.length, c.length, d.length]
|
203
|
+
end
|
204
|
+
|
205
|
+
[0, 0, 0, 0]
|
206
|
+
end
|
207
|
+
|
208
|
+
def get_fnp(start_date, end_date)
|
209
|
+
age_from = 0
|
210
|
+
age_to = 1000
|
211
|
+
yrs_months = 'year'
|
212
|
+
gender = 'F'
|
213
|
+
|
214
|
+
females_pregnant = []
|
215
|
+
cum_females_pregnant = []
|
216
|
+
breast_feeding_women = []
|
217
|
+
cum_breast_feeding_women = []
|
218
|
+
|
219
|
+
started_on_art = []
|
220
|
+
alive_on_art = []
|
221
|
+
started_on_ipt = []
|
222
|
+
screened_for_tb = []
|
223
|
+
|
224
|
+
###############################################################
|
225
|
+
(@cohort.total_breastfeeding_women || []).each do |p|
|
226
|
+
date_enrolled_str = ActiveRecord::Base.connection.select_one(
|
227
|
+
"SELECT date_enrolled FROM temp_earliest_start_date e
|
228
|
+
WHERE patient_id = #{p['person_id']} #{site_manager(operator: 'AND', column: 'e.site_id',
|
229
|
+
location: @location)}"
|
230
|
+
)
|
231
|
+
|
232
|
+
date_enrolled = date_enrolled_str['date_enrolled'].to_date
|
233
|
+
if (date_enrolled >= start_date.to_date) && (end_date.to_date <= end_date.to_date)
|
234
|
+
breast_feeding_women << p['person_id'].to_i
|
235
|
+
breast_feeding_women = breast_feeding_women.uniq
|
236
|
+
else
|
237
|
+
cum_breast_feeding_women << p['person_id'].to_i
|
238
|
+
cum_breast_feeding_women = cum_breast_feeding_women.uniq
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
cum_pregnant_women = @cohort.total_pregnant_women
|
243
|
+
(cum_pregnant_women || []).each do |p|
|
244
|
+
next if breast_feeding_women.include?(p['person_id'].to_i)
|
245
|
+
|
246
|
+
date_enrolled_str = ActiveRecord::Base.connection.select_one(
|
247
|
+
"SELECT date_enrolled FROM temp_earliest_start_date e
|
248
|
+
WHERE patient_id = #{p['person_id'].to_i} #{site_manager(operator: 'AND', column: 'e.site_id',
|
249
|
+
location: @location)}"
|
250
|
+
)
|
251
|
+
|
252
|
+
date_enrolled = date_enrolled_str['date_enrolled'].to_date
|
253
|
+
if (date_enrolled >= start_date.to_date) && (end_date.to_date <= end_date.to_date)
|
254
|
+
females_pregnant << p['person_id'].to_i
|
255
|
+
females_pregnant = females_pregnant.uniq
|
256
|
+
else
|
257
|
+
cum_females_pregnant << p['person_id'].to_i
|
258
|
+
cum_females_pregnant = cum_females_pregnant.uniq
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
cum_females_pregnant = (cum_females_pregnant + females_pregnant)&.uniq || []
|
263
|
+
cum_breast_feeding_women += breast_feeding_women
|
264
|
+
#####################################################################
|
265
|
+
|
266
|
+
(get_started_on_art(yrs_months, age_from, age_to, gender, start_date, end_date) || []).each do |fnp|
|
267
|
+
next if females_pregnant.include?(fnp['patient_id'].to_i)
|
268
|
+
next if breast_feeding_women.include?(fnp['patient_id'].to_i)
|
269
|
+
|
270
|
+
started_on_art << { patient_id: fnp['patient_id'].to_i, date_enrolled: fnp['date_enrolled'].to_date }
|
271
|
+
end
|
272
|
+
|
273
|
+
(get_alive_on_art(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date) || []).each do |fnp|
|
274
|
+
next if cum_females_pregnant.include?(fnp['patient_id'].to_i)
|
275
|
+
next if cum_breast_feeding_women.include?(fnp['patient_id'].to_i)
|
276
|
+
|
277
|
+
alive_on_art << { patient_id: fnp['patient_id'].to_i }
|
278
|
+
end
|
279
|
+
|
280
|
+
(get_started_on_ipt(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date) || []).each do |fnp|
|
281
|
+
next if cum_females_pregnant.include?(fnp['patient_id'].to_i)
|
282
|
+
next if cum_breast_feeding_women.include?(fnp['patient_id'].to_i)
|
283
|
+
|
284
|
+
started_on_ipt << { patient_id: fnp['patient_id'].to_i }
|
285
|
+
end
|
286
|
+
|
287
|
+
(get_screened_for_tb(yrs_months, age_from, age_to, gender, @cohort_cum_start_date,
|
288
|
+
end_date) || []).each do |fnp|
|
289
|
+
next if cum_females_pregnant.include?(fnp['patient_id'].to_i)
|
290
|
+
next if cum_breast_feeding_women.include?(fnp['patient_id'].to_i)
|
291
|
+
|
292
|
+
screened_for_tb << { patient_id: fnp['patient_id'].to_i }
|
293
|
+
end
|
294
|
+
|
295
|
+
[started_on_art, alive_on_art, started_on_ipt, screened_for_tb]
|
296
|
+
end
|
297
|
+
|
298
|
+
def get_screened_for_tb(yrs_months, age_from, age_to, gender, start_date, end_date)
|
299
|
+
alive_on_art_patient_ids = []
|
300
|
+
start_date = @cohort_cum_start_date
|
301
|
+
|
302
|
+
(@cohort.total_alive_and_on_art || []).each do |data|
|
303
|
+
alive_on_art_patient_ids << data['patient_id'].to_i
|
304
|
+
end
|
305
|
+
|
306
|
+
return [] if alive_on_art_patient_ids.blank?
|
307
|
+
|
308
|
+
tb_treatment = concept_name('TB treatment').concept_id
|
309
|
+
tb_status_id = concept_name('TB status').concept_id
|
310
|
+
clinical_consultation = encounter_type('HIV CLINIC CONSULTATION').id
|
311
|
+
|
312
|
+
ActiveRecord::Base.connection.select_all <<~SQL
|
313
|
+
SELECT t1.patient_id
|
314
|
+
FROM obs t3
|
315
|
+
INNER JOIN temp_earliest_start_date t1 ON t1.patient_id = t3.person_id #{site_manager(operator: 'AND', column: 't1.site_id', location: @location)} AND t1.patient_id IN(#{alive_on_art_patient_ids.join(',')})
|
316
|
+
WHERE t3.concept_id IN(#{tb_treatment},#{tb_status_id}) AND t3.voided = 0
|
317
|
+
AND t3.obs_datetime BETWEEN '#{start_date.to_date.strftime('%Y-%m-%d 00:00:00')}' AND '#{end_date.to_date.strftime('%Y-%m-%d 23:59:59')}'
|
318
|
+
AND gender = '#{gender.first}' AND t1.date_enrolled BETWEEN '#{start_date.to_date}' AND '#{end_date.to_date}' #{site_manager(operator: 'AND', column: 't3.site_id', location: @location)}
|
319
|
+
AND #{timestampdiff_manager(date1: 'birthdate', date2: "DATE('#{end_date.to_date}')", interval: yrs_months)} BETWEEN #{age_from} AND #{age_to}
|
320
|
+
AND t3.obs_datetime = (
|
321
|
+
SELECT MAX(obs_datetime)
|
322
|
+
FROM obs t4
|
323
|
+
INNER JOIN encounter e ON e.encounter_id = t4.encounter_id AND e.encounter_type = #{clinical_consultation} AND e.voided = 0 #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
|
324
|
+
WHERE t3.person_id = t4.person_id
|
325
|
+
AND t4.voided = 0 #{site_manager(operator: 'AND', column: 't4.site_id', location: @location)}
|
326
|
+
AND t4.obs_datetime BETWEEN '#{start_date.to_date.strftime('%Y-%m-%d 00:00:00')}' AND '#{end_date.to_date.strftime('%Y-%m-%d 23:59:59')}'
|
327
|
+
)
|
328
|
+
GROUP BY t3.person_id
|
329
|
+
SQL
|
330
|
+
end
|
331
|
+
|
332
|
+
def get_started_on_ipt(yrs_months, age_from, age_to, gender, _start_date, end_date)
|
333
|
+
data = ActiveRecord::Base.connection.select_all <<~SQL
|
334
|
+
SELECT patient_id
|
335
|
+
FROM temp_earliest_start_date
|
336
|
+
WHERE gender = '#{gender}' AND earliest_start_date <= '#{end_date.to_date}'
|
337
|
+
AND #{timestampdiff_manager(date1: 'birthdate', date2: "DATE('#{end_date.to_date}')", interval: yrs_months)}
|
338
|
+
BETWEEN #{age_from} AND #{age_to} #{site_manager(operator: 'AND', column: 'site_id', location: @location)}
|
339
|
+
SQL
|
340
|
+
|
341
|
+
return [] if data.blank?
|
342
|
+
|
343
|
+
patient_ids = []
|
344
|
+
|
345
|
+
data.each do |d|
|
346
|
+
patient_ids << d['patient_id'].to_i
|
347
|
+
end
|
348
|
+
|
349
|
+
amount_dispensed = concept_name('Amount dispensed').concept_id
|
350
|
+
ipt_drug_ids = ::Drug.where(concept_id: concept_name('Isoniazid').concept_id).map(&:drug_id)
|
351
|
+
|
352
|
+
ActiveRecord::Base.connection.select_all <<~SQL
|
353
|
+
SELECT obs.person_id patient_id
|
354
|
+
FROM obs
|
355
|
+
WHERE concept_id = #{amount_dispensed} AND obs.voided = 0 #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
356
|
+
AND obs.obs_datetime <= '#{end_date.to_date.strftime('%Y-%m-%d 23:59:59')}'
|
357
|
+
AND value_drug IN(#{ipt_drug_ids.join(',')}) AND obs.person_id IN(#{patient_ids.join(',')})
|
358
|
+
SQL
|
359
|
+
end
|
360
|
+
|
361
|
+
def get_alive_on_art(yrs_months, age_from, age_to, gender, _start_date, end_date)
|
362
|
+
alive_on_art_patient_ids = []
|
363
|
+
|
364
|
+
(@cohort.total_alive_and_on_art || []).each do |data|
|
365
|
+
alive_on_art_patient_ids << data['patient_id'].to_i
|
366
|
+
end
|
367
|
+
|
368
|
+
return [] if alive_on_art_patient_ids.blank?
|
369
|
+
|
370
|
+
ActiveRecord::Base.connection.select_all <<~SQL
|
371
|
+
SELECT patient_id
|
372
|
+
FROM temp_earliest_start_date
|
373
|
+
WHERE gender = '#{gender}' AND date_enrolled <= '#{end_date.to_date}' AND
|
374
|
+
patient_id IN(#{alive_on_art_patient_ids.join(',')})
|
375
|
+
AND #{timestampdiff_manager(date1: 'birthdate', date2: "DATE('#{end_date.to_date}')", interval: yrs_months)}
|
376
|
+
BETWEEN #{age_from} AND #{age_to} #{site_manager(operator: 'AND', column: 'site_id', location: @location)}
|
377
|
+
SQL
|
378
|
+
end
|
379
|
+
|
380
|
+
def get_started_on_art(yrs_months, age_from, age_to, gender, start_date, end_date)
|
381
|
+
ActiveRecord::Base.connection.select_all <<~SQL
|
382
|
+
SELECT patient_id, date_enrolled
|
383
|
+
FROM temp_earliest_start_date
|
384
|
+
WHERE gender = '#{gender}' AND date_enrolled BETWEEN
|
385
|
+
'#{start_date.to_date}' AND '#{end_date.to_date}' AND
|
386
|
+
(DATE(date_enrolled) = DATE(earliest_start_date))
|
387
|
+
AND #{timestampdiff_manager(date1: 'birthdate', date2: 'DATE(earliest_start_date)', interval: yrs_months)}
|
388
|
+
BETWEEN #{age_from} AND #{age_to} #{site_manager(operator: 'AND', column: 'site_id', location: @location)}
|
389
|
+
SQL
|
390
|
+
end
|
391
|
+
|
392
|
+
def get_fp(start_date, end_date)
|
393
|
+
age_from = 0
|
394
|
+
age_to = 1000
|
395
|
+
yrs_months = 'year'
|
396
|
+
gender = 'F'
|
397
|
+
cum_pregnant_women = @cohort.total_pregnant_women
|
398
|
+
|
399
|
+
return [[], [], [], []] if cum_pregnant_women.blank?
|
400
|
+
|
401
|
+
pregnant_women_patient_ids = []
|
402
|
+
|
403
|
+
cum_pregnant_women.each do |p|
|
404
|
+
date_enrolled_str = ActiveRecord::Base.connection.select_one <<~SQL
|
405
|
+
SELECT date_enrolled FROM temp_earliest_start_date e
|
406
|
+
WHERE patient_id = #{p['person_id'].to_i} #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
|
407
|
+
SQL
|
408
|
+
|
409
|
+
date_enrolled = date_enrolled_str['date_enrolled'].to_date
|
410
|
+
if (date_enrolled >= @cohort_cum_start_date.to_date) && (end_date.to_date <= end_date.to_date)
|
411
|
+
pregnant_women_patient_ids << p['person_id'].to_i
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
started_on_art = []
|
416
|
+
alive_on_art = []
|
417
|
+
started_on_ipt = []
|
418
|
+
screened_for_tb = []
|
419
|
+
|
420
|
+
(get_started_on_art(yrs_months, age_from, age_to, gender, start_date, end_date) || []).each do |p|
|
421
|
+
next unless pregnant_women_patient_ids.include?(p['patient_id'].to_i)
|
422
|
+
|
423
|
+
started_on_art << p
|
424
|
+
end
|
425
|
+
|
426
|
+
(get_alive_on_art(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date) || []).each do |p|
|
427
|
+
next unless pregnant_women_patient_ids.include?(p['patient_id'].to_i)
|
428
|
+
|
429
|
+
alive_on_art << { patient_id: p['patient_id'].to_i }
|
430
|
+
end
|
431
|
+
|
432
|
+
(get_started_on_ipt(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date) || []).each do |p|
|
433
|
+
next unless pregnant_women_patient_ids.include?(p['patient_id'].to_i)
|
434
|
+
|
435
|
+
started_on_ipt << { patient_id: p['patient_id'].to_i }
|
436
|
+
end
|
437
|
+
|
438
|
+
(get_screened_for_tb(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date) || []).each do |p|
|
439
|
+
next unless pregnant_women_patient_ids.include?(p['patient_id'].to_i)
|
440
|
+
|
441
|
+
screened_for_tb << { patient_id: p['patient_id'].to_i }
|
442
|
+
end
|
443
|
+
|
444
|
+
[started_on_art, alive_on_art,
|
445
|
+
started_on_ipt, screened_for_tb]
|
446
|
+
end
|
447
|
+
|
448
|
+
def get_fbf(start_date, end_date)
|
449
|
+
age_from = 0
|
450
|
+
age_to = 1000
|
451
|
+
yrs_months = 'year'
|
452
|
+
gender = 'F'
|
453
|
+
cum_breastfeeding_mothers = @cohort.total_breastfeeding_women
|
454
|
+
|
455
|
+
return [[], [], [], []] if cum_breastfeeding_mothers.blank?
|
456
|
+
|
457
|
+
fbf_women_patient_ids = []
|
458
|
+
|
459
|
+
started_on_art = []
|
460
|
+
alive_on_art = []
|
461
|
+
started_on_ipt = []
|
462
|
+
screened_for_tb = []
|
463
|
+
|
464
|
+
#########################################################################
|
465
|
+
cum_pregnant_women = @cohort.total_pregnant_women
|
466
|
+
pregnant_women_patient_ids = []
|
467
|
+
|
468
|
+
cum_pregnant_women.each do |p|
|
469
|
+
date_enrolled_str = ActiveRecord::Base.connection.select_one(
|
470
|
+
"SELECT date_enrolled FROM temp_earliest_start_date e
|
471
|
+
WHERE patient_id = #{p['person_id'].to_i} #{site_manager(operator: 'AND', column: 'e.site_id',
|
472
|
+
location: @location)}"
|
473
|
+
)
|
474
|
+
|
475
|
+
date_enrolled = date_enrolled_str['date_enrolled'].to_date
|
476
|
+
if (date_enrolled >= @cohort_cum_start_date.to_date) && (end_date.to_date <= end_date.to_date)
|
477
|
+
pregnant_women_patient_ids << p['person_id'].to_i
|
478
|
+
end
|
479
|
+
end
|
480
|
+
#########################################################################
|
481
|
+
|
482
|
+
cum_breastfeeding_mothers.each do |w|
|
483
|
+
next if pregnant_women_patient_ids.include?(w['person_id'].to_i)
|
484
|
+
|
485
|
+
date_enrolled_str = ActiveRecord::Base.connection.select_one(
|
486
|
+
"SELECT date_enrolled FROM temp_earliest_start_date e
|
487
|
+
WHERE patient_id = #{w['person_id'].to_i} #{site_manager(operator: 'AND', column: 'e.site_id',
|
488
|
+
location: @location)}"
|
489
|
+
)
|
490
|
+
|
491
|
+
date_enrolled = date_enrolled_str['date_enrolled'].to_date
|
492
|
+
if (date_enrolled >= @cohort_cum_start_date.to_date) && (end_date.to_date <= end_date.to_date)
|
493
|
+
fbf_women_patient_ids << w['person_id'].to_i
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
(get_started_on_art(yrs_months, age_from, age_to, gender, start_date, end_date) || []).each do |fbf|
|
498
|
+
next unless fbf_women_patient_ids.include?(fbf['patient_id'].to_i)
|
499
|
+
|
500
|
+
started_on_art << { patient_id: fbf['patient_id'].to_i, date_enrolled: fbf['date_enrolled'].to_date }
|
501
|
+
end
|
502
|
+
|
503
|
+
(get_alive_on_art(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date) || []).each do |fbf|
|
504
|
+
next unless fbf_women_patient_ids.include?(fbf['patient_id'].to_i)
|
505
|
+
|
506
|
+
alive_on_art << { patient_id: fbf['patient_id'].to_i }
|
507
|
+
end
|
508
|
+
|
509
|
+
(get_started_on_ipt(yrs_months, age_from, age_to, gender, @cohort_cum_start_date, end_date) || []).each do |fbf|
|
510
|
+
next unless fbf_women_patient_ids.include?(fbf['patient_id'].to_i)
|
511
|
+
|
512
|
+
started_on_ipt << { patient_id: fbf['patient_id'].to_i }
|
513
|
+
end
|
514
|
+
|
515
|
+
(get_screened_for_tb(yrs_months, age_from, age_to, gender, @cohort_cum_start_date,
|
516
|
+
end_date) || []).each do |fbf|
|
517
|
+
next unless fbf_women_patient_ids.include?(fbf['patient_id'].to_i)
|
518
|
+
|
519
|
+
screened_for_tb << { patient_id: fbf['patient_id'].to_i }
|
520
|
+
end
|
521
|
+
|
522
|
+
[started_on_art, alive_on_art, started_on_ipt, screened_for_tb]
|
523
|
+
end
|
524
|
+
end
|
525
|
+
end
|
526
|
+
end
|