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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/app/services/malawi_hiv_program_reports/README.md +16 -0
  3. data/app/services/malawi_hiv_program_reports/adapters/moh/custom.rb +199 -0
  4. data/app/services/malawi_hiv_program_reports/archiving_candidates.rb +130 -0
  5. data/app/services/malawi_hiv_program_reports/arv_refill_periods.rb +311 -0
  6. data/app/services/malawi_hiv_program_reports/clinic/README.md +5 -0
  7. data/app/services/malawi_hiv_program_reports/clinic/appointments_report.rb +317 -0
  8. data/app/services/malawi_hiv_program_reports/clinic/discrepancy_report.rb +42 -0
  9. data/app/services/malawi_hiv_program_reports/clinic/docs/hypertension_report.md +31 -0
  10. data/app/services/malawi_hiv_program_reports/clinic/drug_dispensations.rb +48 -0
  11. data/app/services/malawi_hiv_program_reports/clinic/external_consultation_clients.rb +69 -0
  12. data/app/services/malawi_hiv_program_reports/clinic/hypertension_report.rb +223 -0
  13. data/app/services/malawi_hiv_program_reports/clinic/ipt_coverage.rb +112 -0
  14. data/app/services/malawi_hiv_program_reports/clinic/ipt_report.rb +69 -0
  15. data/app/services/malawi_hiv_program_reports/clinic/lims_results.rb +55 -0
  16. data/app/services/malawi_hiv_program_reports/clinic/outcome_list.rb +127 -0
  17. data/app/services/malawi_hiv_program_reports/clinic/patients_alive_and_on_treatment.rb +57 -0
  18. data/app/services/malawi_hiv_program_reports/clinic/patients_due_for_viral_load.rb +39 -0
  19. data/app/services/malawi_hiv_program_reports/clinic/patients_on_antiretrovirals.rb +44 -0
  20. data/app/services/malawi_hiv_program_reports/clinic/patients_on_dtg.rb +36 -0
  21. data/app/services/malawi_hiv_program_reports/clinic/patients_on_treatment.rb +42 -0
  22. data/app/services/malawi_hiv_program_reports/clinic/patients_with_outdated_demographics.rb +173 -0
  23. data/app/services/malawi_hiv_program_reports/clinic/pregnant_patients.rb +91 -0
  24. data/app/services/malawi_hiv_program_reports/clinic/regimen_dispensation_data.rb +282 -0
  25. data/app/services/malawi_hiv_program_reports/clinic/regimen_switch.rb +456 -0
  26. data/app/services/malawi_hiv_program_reports/clinic/regimens_and_formulations.rb +182 -0
  27. data/app/services/malawi_hiv_program_reports/clinic/regimens_by_weight_and_gender.rb +108 -0
  28. data/app/services/malawi_hiv_program_reports/clinic/retention.rb +246 -0
  29. data/app/services/malawi_hiv_program_reports/clinic/stock_card_report.rb +65 -0
  30. data/app/services/malawi_hiv_program_reports/clinic/tpt_outcome.rb +494 -0
  31. data/app/services/malawi_hiv_program_reports/clinic/tx_rtt.rb +169 -0
  32. data/app/services/malawi_hiv_program_reports/clinic/viral_load.rb +292 -0
  33. data/app/services/malawi_hiv_program_reports/clinic/viral_load_disaggregated.rb +97 -0
  34. data/app/services/malawi_hiv_program_reports/clinic/viral_load_results.rb +175 -0
  35. data/app/services/malawi_hiv_program_reports/clinic/visits_report.rb +113 -0
  36. data/app/services/malawi_hiv_program_reports/clinic/vl_collection.rb +48 -0
  37. data/app/services/malawi_hiv_program_reports/cohort/outcomes.rb +338 -0
  38. data/app/services/malawi_hiv_program_reports/cohort/regimens.rb +69 -0
  39. data/app/services/malawi_hiv_program_reports/cohort/side_effects.rb +141 -0
  40. data/app/services/malawi_hiv_program_reports/cohort/tpt.rb +172 -0
  41. data/app/services/malawi_hiv_program_reports/moh/cohort.rb +278 -0
  42. data/app/services/malawi_hiv_program_reports/moh/cohort_builder.rb +2340 -0
  43. data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated.rb +608 -0
  44. data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated_additions.rb +208 -0
  45. data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated_builder.rb +526 -0
  46. data/app/services/malawi_hiv_program_reports/moh/cohort_struct.rb +219 -0
  47. data/app/services/malawi_hiv_program_reports/moh/cohort_survival_analysis.rb +203 -0
  48. data/app/services/malawi_hiv_program_reports/moh/moh_tpt.rb +223 -0
  49. data/app/services/malawi_hiv_program_reports/moh/tpt_newly_initiated.rb +235 -0
  50. data/app/services/malawi_hiv_program_reports/pepfar/defaulter_list.rb +25 -0
  51. data/app/services/malawi_hiv_program_reports/pepfar/maternal_status.rb +29 -0
  52. data/app/services/malawi_hiv_program_reports/pepfar/patient_start_vl.rb +45 -0
  53. data/app/services/malawi_hiv_program_reports/pepfar/regimen_switch.rb +479 -0
  54. data/app/services/malawi_hiv_program_reports/pepfar/sc_arvdisp.rb +174 -0
  55. data/app/services/malawi_hiv_program_reports/pepfar/sc_curr.rb +98 -0
  56. data/app/services/malawi_hiv_program_reports/pepfar/tb_prev.rb +163 -0
  57. data/app/services/malawi_hiv_program_reports/pepfar/tb_prev2.rb +222 -0
  58. data/app/services/malawi_hiv_program_reports/pepfar/tb_prev3.rb +421 -0
  59. data/app/services/malawi_hiv_program_reports/pepfar/tpt_status.rb +181 -0
  60. data/app/services/malawi_hiv_program_reports/pepfar/tx_ml.rb +181 -0
  61. data/app/services/malawi_hiv_program_reports/pepfar/tx_new.rb +202 -0
  62. data/app/services/malawi_hiv_program_reports/pepfar/tx_rtt.rb +288 -0
  63. data/app/services/malawi_hiv_program_reports/pepfar/tx_tb.rb +283 -0
  64. data/app/services/malawi_hiv_program_reports/pepfar/utils.rb +141 -0
  65. data/app/services/malawi_hiv_program_reports/pepfar/viral_load_coverage.rb +414 -0
  66. data/app/services/malawi_hiv_program_reports/pepfar/viral_load_coverage2.rb +433 -0
  67. data/app/services/malawi_hiv_program_reports/report_map.rb +56 -0
  68. data/app/services/malawi_hiv_program_reports/utils/README.md +8 -0
  69. data/app/services/malawi_hiv_program_reports/utils/common_sql_query_utils.rb +60 -0
  70. data/app/services/malawi_hiv_program_reports/utils/concurrency_utils.rb +53 -0
  71. data/app/services/malawi_hiv_program_reports/utils/docs/common_sql_query_utils.md +53 -0
  72. data/app/services/malawi_hiv_program_reports/utils/model_utils.rb +66 -0
  73. data/app/services/malawi_hiv_program_reports/utils/parameter_utils.rb +32 -0
  74. data/app/services/malawi_hiv_program_reports/utils/time_utils.rb +52 -0
  75. data/lib/malawi_hiv_program_reports/version.rb +1 -1
  76. 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