malawi_hiv_program_reports 1.0.25 → 1.0.26

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.
@@ -4,22 +4,39 @@ module MalawiHivProgramReports
4
4
  module Moh
5
5
  # This is the Cumulative Cohort Builder class
6
6
  # rubocop:disable Metrics/ClassLength
7
+ # rubocop:disable Metrics/MethodLength
7
8
  class CumulativeOutcome
8
9
  include MalawiHivProgramReports::Utils::CommonSqlQueryUtils
9
- attr_reader :end_date, :definition, :rebuild, :location
10
+ attr_reader :end_date, :definition, :rebuild, :start_date, :prev_date, :location
10
11
 
11
12
  def initialize(end_date:, definition: 'moh', **kwargs)
13
+ start_date = kwargs[:start_date] || (end_date.to_date - 2.months).beginning_of_month
12
14
  @end_date = ActiveRecord::Base.connection.quote(end_date.to_date)
15
+ @start_date = ActiveRecord::Base.connection.quote(start_date.to_date)
16
+ @prev_date = ActiveRecord::Base.connection.quote((start_date.to_date - 3.months).to_date)
13
17
  @definition = definition
14
18
  @rebuild = kwargs[:rebuild]
15
19
  @location = kwargs[:location]
20
+ Rails.logger.info "Definition: #{definition}. Rebuild: #{@rebuild}. Location: #{@location}. Start date: #{@start_date}. End date: #{@end_date}. Previous date: #{@prev_date}."
16
21
  end
17
22
 
18
23
  def find_report
19
24
  prepare_tables
20
- clear_tables if rebuild
21
- update_steps unless rebuild
22
- process_data
25
+ [false, true].each do |start|
26
+ clear_tables(start:) if rebuild
27
+ update_steps(start:, portion: false) unless rebuild
28
+ process_data(start:)
29
+ end
30
+ end
31
+
32
+ def update_outcomes_by_definition
33
+ prepare_tables
34
+ [false, true].each do |start|
35
+ update_steps(start: start, portion: true)
36
+ load_patients_on_treatment(start:)
37
+ load_without_clinical_contact(start:)
38
+ load_defaulters(start:)
39
+ end
23
40
  end
24
41
 
25
42
  private
@@ -45,49 +62,67 @@ module MalawiHivProgramReports
45
62
  # Data Management Region
46
63
  # ===================================
47
64
  # rubocop:disable Metrics/MethodLength
48
- def process_data
49
- denormalize
65
+ def process_data(start: false)
66
+ denormalize(start:)
50
67
  # HIC SUNT DRACONIS: The order of the operations below matters,
51
68
  # do not change it unless you know what you are doing!!!
52
- load_patients_who_died
53
- load_patients_who_stopped_treatment
54
- load_patients_without_drug_orders
55
- load_patients_on_treatment
56
- load_without_clinical_contact
57
- load_defaulters
58
- end
59
-
60
- def denormalize
61
- load_max_drug_orders
62
- load_patient_current_medication
63
- update_patient_current_medication
64
- load_min_auto_expire_date
65
- load_max_patient_state
66
- load_patient_current_state
67
- update_patient_current_state
68
- end
69
-
70
- def load_max_drug_orders
71
- ActiveRecord::Base.connection.execute <<~SQL
72
- INSERT INTO cdr_temp_max_drug_orders PARTITION (p#{location})
73
- SELECT o.patient_id, o.site_id, MAX(o.start_date) AS start_date
74
- FROM orders o
75
- INNER JOIN cdr_temp_cohort_members tesd ON tesd.patient_id = o.patient_id AND tesd.site_id = o.site_id
76
- INNER JOIN drug_order ON drug_order.order_id = o.order_id
69
+ load_patients_who_died(start:)
70
+ load_patients_who_stopped_treatment(start:)
71
+ load_patients_without_drug_orders(start:)
72
+ load_patients_on_treatment(start:)
73
+ load_without_clinical_contact(start:)
74
+ load_defaulters(start:)
75
+ end
76
+
77
+ def denormalize(start: false)
78
+ load_max_drug_orders(start:)
79
+ update_max_drug_orders(start:)
80
+ load_patient_current_medication(start:)
81
+ update_patient_current_medication(start:)
82
+ load_min_auto_expire_date(start:)
83
+ load_max_patient_state(start:)
84
+ load_patient_current_state(start:)
85
+ update_patient_current_state(start:)
86
+ end
87
+
88
+ def load_max_drug_orders(start: false)
89
+ ActiveRecord::Base.connection.execute <<~SQL
90
+ INSERT INTO cdr_temp_max_drug_orders#{start ? '_start' : ''} PARTITION (p#{location})
91
+ SELECT o.patient_id, o.site_id, MAX(o.start_date) AS start_date, NUll
92
+ FROM orders PARTITION (p#{location}) AS o
93
+ INNER JOIN cdr_temp_cohort_members PARTITION (p#{location}) AS tesd ON tesd.patient_id = o.patient_id AND tesd.site_id = o.site_id
94
+ INNER JOIN drug_order PARTITION (p#{location}) ON drug_order.order_id = o.order_id
77
95
  AND drug_order.site_id = o.site_id AND drug_order.quantity > 0
78
96
  AND drug_order.drug_inventory_id IN (#{arv_drug})
79
97
  WHERE o.order_type_id = 1 -- drug order
80
- AND o.start_date < (DATE(#{end_date}) + INTERVAL 1 DAY)
81
- AND o.voided = 0 AND o.site_id = #{location}
82
- GROUP BY o.patient_id, o.site_id
83
- ON DUPLICATE KEY UPDATE start_date = VALUES(start_date)
98
+ AND o.start_date < (DATE(#{start ? start_date : end_date }) + INTERVAL 1 DAY)
99
+ AND o.voided = 0
100
+ GROUP BY o.patient_id
101
+ ON DUPLICATE KEY UPDATE start_date = VALUES(start_date), min_order_date = VALUES(min_order_date)
102
+ SQL
103
+ end
104
+
105
+ def update_max_drug_orders(start: false)
106
+ ActiveRecord::Base.connection.execute <<~SQL
107
+ INSERT INTO cdr_temp_max_drug_orders#{start ? '_start' : ''} PARTITION (p#{location})
108
+ SELECT o.patient_id, #{location}, MAX(o.start_date) AS start_date, MIN(o.start_date) AS min_order_date
109
+ FROM orders PARTITION (p#{location}) AS o
110
+ INNER JOIN cdr_temp_cohort_members PARTITION (p#{location}) AS tesd ON tesd.patient_id = o.patient_id
111
+ INNER JOIN drug_order PARTITION (p#{location}) ON drug_order.order_id = o.order_id AND drug_order.quantity > 0
112
+ AND drug_order.drug_inventory_id IN (#{arv_drug})
113
+ WHERE o.order_type_id = 1 -- drug order
114
+ AND o.start_date < (DATE(#{start ? start_date : end_date }) + INTERVAL 1 DAY)
115
+ AND o.start_date >= (DATE(#{start ? prev_date : start_date }) + INTERVAL 1 DAY)
116
+ AND o.voided = 0
117
+ GROUP BY o.patient_id
118
+ ON DUPLICATE KEY UPDATE start_date = VALUES(start_date), min_order_date = VALUES(min_order_date)
84
119
  SQL
85
120
  end
86
121
 
87
- def load_patient_current_medication
122
+ def load_patient_current_medication(start: false)
88
123
  ActiveRecord::Base.connection.execute <<~SQL
89
- INSERT INTO cdr_temp_current_medication PARTITION (p#{location})
90
- SELECT mdo.patient_id, mdo.site_id, d.concept_id, do.drug_inventory_id drug_id,
124
+ INSERT INTO cdr_temp_current_medication#{start ? '_start' : ''} PARTITION (p#{location})
125
+ SELECT mdo.patient_id, #{location}, d.concept_id, do.drug_inventory_id drug_id,
91
126
  CASE
92
127
  WHEN do.equivalent_daily_dose IS NULL THEN 1
93
128
  WHEN do.equivalent_daily_dose = 0 THEN 1
@@ -96,143 +131,135 @@ module MalawiHivProgramReports
96
131
  END daily_dose,
97
132
  SUM(do.quantity) quantity,
98
133
  DATE(mdo.start_date) start_date, null, null, null, null
99
- FROM cdr_temp_max_drug_orders mdo
100
- INNER JOIN orders o ON o.patient_id = mdo.patient_id AND o.site_id = mdo.site_id AND o.order_type_id = 1 AND DATE(o.start_date) = DATE(mdo.start_date) AND o.voided = 0
101
- INNER JOIN drug_order do ON do.order_id = o.order_id AND do.site_id = o.site_id AND do.quantity > 0 AND do.drug_inventory_id IN (#{arv_drug})
134
+ FROM cdr_temp_max_drug_orders#{start ? '_start' : ''} PARTITION (p#{location}) AS mdo
135
+ INNER JOIN orders PARTITION (p#{location}) AS o ON o.patient_id = mdo.patient_id AND o.order_type_id = 1 AND DATE(o.start_date) = DATE(mdo.start_date) AND o.voided = 0
136
+ INNER JOIN drug_order PARTITION (p#{location}) AS do ON do.order_id = o.order_id AND do.quantity > 0 AND do.drug_inventory_id IN (#{arv_drug})
102
137
  INNER JOIN drug d ON d.drug_id = do.drug_inventory_id
103
- WHERE mdo.site_id = #{location}
104
138
  GROUP BY mdo.patient_id, do.drug_inventory_id HAVING quantity < 6000
105
139
  ON DUPLICATE KEY UPDATE concept_id = VALUES(concept_id), daily_dose = VALUES(daily_dose), quantity=VALUES(quantity), start_date = VALUES(start_date), pill_count = VALUES(pill_count), expiry_date = VALUES(expiry_date), pepfar_defaulter_date = VALUES(pepfar_defaulter_date), moh_defaulter_date = VALUES(moh_defaulter_date)
106
140
  SQL
107
141
  end
108
142
 
109
- def update_patient_current_medication
143
+ def update_patient_current_medication(start: false)
110
144
  ActiveRecord::Base.connection.execute <<~SQL
111
- INSERT INTO cdr_temp_current_medication PARTITION (p#{location})
112
- SELECT cm.patient_id, cm.site_id, cm.concept_id, cm.drug_id, cm.daily_dose, cm.quantity, cm.start_date,
145
+ INSERT INTO cdr_temp_current_medication#{start ? '_start' : ''} PARTITION (p#{location})
146
+ SELECT cm.patient_id, #{location}, cm.concept_id, cm.drug_id, cm.daily_dose, cm.quantity, cm.start_date,
113
147
  COALESCE(first_ob.quantity, 0) + COALESCE(SUM(second_ob.value_numeric),0) + COALESCE(SUM(third_ob.value_numeric),0) AS pill_count,
114
- DATE_ADD(DATE_SUB(cm.start_date, INTERVAL 1 DAY), INTERVAL (cm.quantity + COALESCE(first_ob.quantity, 0) + COALESCE(SUM(second_ob.value_numeric),0) + COALESCE(SUM(third_ob.value_numeric),0)) / cm.daily_dose DAY),
115
- DATE_ADD(DATE_ADD(DATE_SUB(cm.start_date, INTERVAL 1 DAY), INTERVAL (cm.quantity + COALESCE(first_ob.quantity, 0) + COALESCE(SUM(second_ob.value_numeric),0) + COALESCE(SUM(third_ob.value_numeric),0)) / cm.daily_dose DAY), INTERVAL 30 DAY),
116
- DATE_ADD(DATE_ADD(DATE_SUB(cm.start_date, INTERVAL 1 DAY), INTERVAL (cm.quantity + COALESCE(first_ob.quantity, 0) + COALESCE(SUM(second_ob.value_numeric),0) + COALESCE(SUM(third_ob.value_numeric),0)) / cm.daily_dose DAY), INTERVAL 60 DAY)
117
- FROM cdr_temp_current_medication cm
148
+ DATE_ADD(cm.start_date, INTERVAL (cm.quantity + COALESCE(first_ob.quantity, 0) + COALESCE(SUM(second_ob.value_numeric),0) + COALESCE(SUM(third_ob.value_numeric),0)) / cm.daily_dose DAY),
149
+ DATE_ADD(DATE_ADD(cm.start_date, INTERVAL (cm.quantity + COALESCE(first_ob.quantity, 0) + COALESCE(SUM(second_ob.value_numeric),0) + COALESCE(SUM(third_ob.value_numeric),0)) / cm.daily_dose DAY), INTERVAL 30 DAY),
150
+ DATE_ADD(DATE_ADD(cm.start_date, INTERVAL (cm.quantity + COALESCE(first_ob.quantity, 0) + COALESCE(SUM(second_ob.value_numeric),0) + COALESCE(SUM(third_ob.value_numeric),0)) / cm.daily_dose DAY), INTERVAL 60 DAY)
151
+ FROM cdr_temp_current_medication#{start ? '_start' : ''} PARTITION (p#{location}) AS cm
118
152
  LEFT JOIN (
119
- SELECT ob.person_id,ob.site_id, cm.drug_id,
120
- SUM(ob.value_numeric) + SUM(CASE
121
- WHEN ob.value_text is null then 0
122
- WHEN ob.value_text REGEXP '^[0-9]+(.[0-9]+)?$' then ob.value_text
123
- ELSE 0
124
- END) quantity
125
- FROM obs ob
126
- INNER JOIN cdr_temp_current_medication cm ON cm.patient_id = ob.person_id AND cm.site_id = ob.site_id AND cm.start_date = DATE(ob.obs_datetime)
127
- INNER JOIN orders o ON o.order_id = ob.order_id AND o.site_id = ob.site_id AND o.voided = 0
128
- INNER JOIN drug_order do ON do.order_id = o.order_id AND do.site_id = o.site_id AND do.drug_inventory_id = cm.drug_id
129
- WHERE ob.concept_id = 2540 AND ob.voided = 0 AND ob.site_id = #{location}
130
- GROUP BY ob.person_id, cm.drug_id
131
- ) first_ob ON first_ob.person_id = cm.patient_id AND first_ob.site_id = cm.site_id AND first_ob.drug_id = cm.drug_id
132
- LEFT JOIN obs second_ob ON second_ob.person_id = cm.patient_id AND second_ob.site_id = cm.site_id AND second_ob.concept_id = cm.concept_id AND DATE(second_ob.obs_datetime) = cm.start_date AND second_ob.voided = 0
133
- LEFT JOIN obs third_ob ON third_ob.person_id = cm.patient_id AND third_ob.site_id = cm.site_id AND third_ob.concept_id = 2540 AND third_ob.value_drug = cm.drug_id AND third_ob.voided = 0 AND DATE(third_ob.obs_datetime) = cm.start_date
134
- WHERE cm.site_id = #{location}
153
+ SELECT ob.person_id, #{location}, cm.drug_id,
154
+ SUM(ob.value_numeric) + SUM(CASE
155
+ WHEN ob.value_text is null then 0
156
+ WHEN ob.value_text REGEXP '^[0-9]+(.[0-9]+)?$' then ob.value_text
157
+ ELSE 0
158
+ END) quantity
159
+ FROM obs PARTITION (p#{location}) AS ob
160
+ INNER JOIN cdr_temp_current_medication#{start ? '_start' : ''} PARTITION (p#{location}) cm ON cm.patient_id = ob.person_id AND cm.start_date = DATE(ob.obs_datetime)
161
+ INNER JOIN orders PARTITION (p#{location}) o ON o.order_id = ob.order_id AND o.voided = 0
162
+ INNER JOIN drug_order PARTITION (p#{location}) AS do ON do.order_id = o.order_id AND do.drug_inventory_id = cm.drug_id
163
+ WHERE ob.concept_id = 2540 AND ob.voided = 0
164
+ GROUP BY ob.person_id, cm.drug_id
165
+ ) first_ob ON first_ob.person_id = cm.patient_id AND first_ob.drug_id = cm.drug_id
166
+ LEFT JOIN obs PARTITION (p#{location}) As second_ob ON second_ob.person_id = cm.patient_id AND second_ob.concept_id = cm.concept_id AND DATE(second_ob.obs_datetime) = cm.start_date AND second_ob.voided = 0
167
+ LEFT JOIN obs PARTITION (p#{location}) AS third_ob ON third_ob.person_id = cm.patient_id AND third_ob.concept_id = 2540 AND third_ob.value_drug = cm.drug_id AND third_ob.voided = 0 AND DATE(third_ob.obs_datetime) = cm.start_date
135
168
  GROUP BY cm.patient_id, cm.drug_id
136
169
  ON DUPLICATE KEY UPDATE pill_count = VALUES(pill_count), expiry_date = VALUES(expiry_date), pepfar_defaulter_date = VALUES(pepfar_defaulter_date), moh_defaulter_date = VALUES(moh_defaulter_date);
137
170
  SQL
138
171
  end
139
172
 
140
- def load_min_auto_expire_date
173
+ def load_min_auto_expire_date(start: false)
141
174
  ActiveRecord::Base.connection.execute <<~SQL
142
- INSERT INTO cdr_temp_min_auto_expire_date PARTITION (p#{location})
143
- SELECT cm.patient_id, cm.site_id, MIN(cm.start_date), MIN(cm.expiry_date), MIN(cm.pepfar_defaulter_date), MIN(cm.moh_defaulter_date)
144
- FROM cdr_temp_current_medication cm
145
- WHERE cm.site_id = #{location}
175
+ INSERT INTO cdr_temp_min_auto_expire_date#{start ? '_start' : ''} PARTITION (p#{location})
176
+ SELECT cm.patient_id, #{location}, MIN(cm.start_date), MIN(cm.expiry_date), MIN(cm.pepfar_defaulter_date), MIN(cm.moh_defaulter_date)
177
+ FROM cdr_temp_current_medication#{start ? '_start' : ''} PARTITION (p#{location}) AS cm
146
178
  GROUP BY cm.patient_id
147
179
  ON DUPLICATE KEY UPDATE start_date = VALUES(start_date), auto_expire_date = VALUES(auto_expire_date), pepfar_defaulter_date = VALUES(pepfar_defaulter_date), moh_defaulter_date = VALUES(moh_defaulter_date)
148
180
  SQL
149
181
  end
150
182
 
151
- def load_max_patient_state
183
+ def load_max_patient_state(start: false)
152
184
  ActiveRecord::Base.connection.execute <<~SQL
153
- INSERT INTO cdr_temp_max_patient_state PARTITION (p#{location})
154
- SELECT pp.patient_id, pp.site_id, MAX(ps.start_date) start_date
155
- FROM patient_state ps
156
- INNER JOIN patient_program pp ON pp.patient_program_id = ps.patient_program_id AND pp.site_id = ps.site_id AND pp.program_id = 1 AND pp.voided = 0
185
+ INSERT INTO cdr_temp_max_patient_state#{start ? '_start' : ''} PARTITION (p#{location})
186
+ SELECT pp.patient_id, #{location}, MAX(ps.start_date) start_date
187
+ FROM patient_state PARTITION (p#{location}) AS ps
188
+ INNER JOIN patient_program PARTITION (p#{location}) AS pp ON pp.patient_program_id = ps.patient_program_id AND pp.program_id = 1 AND pp.voided = 0
157
189
  WHERE ps.start_date < DATE(#{end_date}) + INTERVAL 1 DAY
158
- AND ps.voided = 0 AND ps.site_id = #{location} AND pp.patient_id IN (SELECT patient_id FROM temp_earliest_start_date WHERE site_id = #{location})
159
- GROUP BY pp.patient_id, pp.site_id
190
+ AND ps.voided = 0 AND pp.patient_id IN (SELECT patient_id FROM cdr_temp_cohort_members PARTITION (p#{location}))
191
+ GROUP BY pp.patient_id
160
192
  HAVING start_date IS NOT NULL
161
193
  ON DUPLICATE KEY UPDATE start_date = VALUES(start_date)
162
194
  SQL
163
195
  end
164
196
 
165
- def load_patient_current_state
197
+ def load_patient_current_state(start: false)
166
198
  ActiveRecord::Base.connection.execute <<~SQL
167
- INSERT INTO cdr_temp_current_state PARTITION (p#{location})
168
- SELECT mps.patient_id, mps.site_id, cn.name AS cum_outcome, ps.start_date as outcome_date, ps.state, count(DISTINCT(ps.state)) outcomes, MAX(ps.patient_state_id) patient_state_id
169
- FROM cdr_temp_max_patient_state mps
170
- INNER JOIN patient_program pp ON pp.patient_id = mps.patient_id AND pp.site_id = mps.site_id AND pp.program_id = 1 AND pp.voided = 0
171
- INNER JOIN patient_state ps ON ps.patient_program_id = pp.patient_program_id AND ps.site_id = pp.site_id AND ps.start_date = mps.start_date AND ps.voided = 0
199
+ INSERT INTO cdr_temp_current_state#{start ? '_start' : ''} PARTITION (p#{location})
200
+ SELECT mps.patient_id, #{location}, cn.name AS cum_outcome, ps.start_date as outcome_date, ps.state, count(DISTINCT(ps.state)) outcomes, MAX(ps.patient_state_id) patient_state_id
201
+ FROM cdr_temp_max_patient_state#{start ? '_start' : ''} PARTITION (p#{location}) AS mps
202
+ INNER JOIN patient_program PARTITION (p#{location}) AS pp ON pp.patient_id = mps.patient_id AND pp.program_id = 1 AND pp.voided = 0
203
+ INNER JOIN patient_state PARTITION (p#{location}) AS ps ON ps.patient_program_id = pp.patient_program_id AND ps.start_date = mps.start_date AND ps.voided = 0
172
204
  AND (ps.end_date IS NULL OR ps.end_date > DATE(#{end_date}))
173
205
  INNER JOIN program_workflow_state pws ON pws.program_workflow_state_id = ps.state AND pws.retired = 0
174
206
  INNER JOIN concept_name cn ON cn.concept_id = pws.concept_id AND cn.concept_name_type = 'FULLY_SPECIFIED' AND cn.voided = 0
175
- LEFT JOIN patient_state ps2 ON ps.patient_program_id = ps2.patient_program_id AND ps2.site_id = ps.site_id AND ps.start_date = ps2.start_date AND ps.date_created < ps2.date_created AND ps2.voided = 0
176
- WHERE ps2.patient_program_id IS NULL AND ps.voided = 0 AND mps.site_id = #{location}
207
+ LEFT JOIN patient_state PARTITION (p#{location}) AS ps2 ON ps.patient_program_id = ps2.patient_program_id AND ps.start_date = ps2.start_date AND ps.date_created < ps2.date_created AND ps2.voided = 0
208
+ WHERE ps2.patient_program_id IS NULL AND ps.voided = 0
177
209
  GROUP BY mps.patient_id
178
210
  ON DUPLICATE KEY UPDATE cum_outcome = VALUES(cum_outcome), outcome_date = VALUES(outcome_date), state = VALUES(state), outcomes = VALUES(outcomes)
179
211
  SQL
180
212
  end
181
213
 
182
- def update_patient_current_state
214
+ def update_patient_current_state(start: false)
183
215
  ActiveRecord::Base.connection.execute <<~SQL
184
- INSERT INTO cdr_temp_current_state
185
- SELECT cs.patient_id, cs.site_id, cn.name as cum_outcome, ps.start_date as outcome_date, ps.state, 1, cs.patient_state_id
186
- FROM patient_state ps
187
- INNER JOIN cdr_temp_current_state cs ON cs.patient_state_id = ps.patient_state_id AND cs.site_id = ps.site_id
216
+ INSERT INTO cdr_temp_current_state#{start ? '_start' : ''} PARTITION (p#{location})
217
+ SELECT cs.patient_id, #{location}, cn.name as cum_outcome, ps.start_date as outcome_date, ps.state, 1, cs.patient_state_id
218
+ FROM patient_state PARTITION (p#{location}) ps
219
+ INNER JOIN cdr_temp_current_state#{start ? '_start' : ''} PARTITION (p#{location}) AS cs ON cs.patient_state_id = ps.patient_state_id AND cs.site_id = ps.site_id
188
220
  INNER JOIN program_workflow_state pws ON pws.program_workflow_state_id = ps.state AND pws.retired = 0
189
221
  INNER JOIN concept_name cn ON cn.concept_id = pws.concept_id AND cn.concept_name_type = 'FULLY_SPECIFIED' AND cn.voided = 0
190
- WHERE ps.voided = 0 AND cs.outcomes > 1 AND cs.site_id = #{location}
222
+ WHERE ps.voided = 0 AND cs.outcomes > 1
191
223
  ON DUPLICATE KEY UPDATE cum_outcome = VALUES(cum_outcome), outcome_date = VALUES(outcome_date), state = VALUES(state), outcomes = VALUES(outcomes), patient_state_id = VALUES(patient_state_id)
192
224
  SQL
193
225
  end
194
226
 
195
227
  # Loads all patiens with an outcome of died as of given date
196
228
  # into the temp_patient_outcomes table.
197
- def load_patients_who_died
229
+ def load_patients_who_died(start: false)
198
230
  ActiveRecord::Base.connection.execute <<~SQL
199
- INSERT INTO cdr_temp_patient_outcomes PARTITION (p#{location})
200
- SELECT patients.patient_id, 'Patient died', patient_state.start_date, patients.site_id, 1
201
- FROM cdr_temp_cohort_members AS patients
202
- INNER JOIN patient_program
231
+ INSERT INTO cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location})
232
+ SELECT patients.patient_id, 'Patient died', patient_state.start_date, #{location}, 1
233
+ FROM cdr_temp_cohort_members PARTITION (p#{location}) AS patients
234
+ INNER JOIN patient_program PARTITION (p#{location})
203
235
  ON patient_program.patient_id = patients.patient_id
204
- AND patient_program.site_id = patients.site_id
205
236
  AND patient_program.program_id = 1
206
237
  AND patient_program.voided = 0
207
- INNER JOIN patient_state
238
+ INNER JOIN patient_state PARTITION (p#{location})
208
239
  ON patient_state.patient_program_id = patient_program.patient_program_id
209
- AND patient_state.site_id = patient_program.site_id
210
240
  AND patient_state.state = (#{program_states('Patient died').limit(1).to_sql})
211
241
  AND patient_state.start_date < DATE(#{end_date}) + INTERVAL 1 DAY
212
242
  AND patient_state.voided = 0
213
- WHERE patients.date_enrolled <= DATE(#{end_date}) AND patients.site_id = #{location}
243
+ WHERE patients.date_enrolled <= DATE(#{end_date})
214
244
  AND patient_state.date_created = (
215
245
  SELECT MAX(date_created)
216
- FROM patient_state ps
217
- WHERE ps.patient_program_id = patient_state.patient_program_id AND ps.site_id = patient_state.site_id
246
+ FROM patient_state PARTITION (p#{location}) ps
247
+ WHERE ps.patient_program_id = patient_state.patient_program_id
218
248
  AND ps.state = patient_state.state AND ps.voided = 0 AND ps.start_date <= #{end_date})
219
- GROUP BY patients.patient_id, patients.site_id
249
+ GROUP BY patients.patient_id
220
250
  ON DUPLICATE KEY UPDATE cum_outcome = VALUES(cum_outcome), outcome_date = VALUES(outcome_date), step = VALUES(step)
221
251
  SQL
222
252
  end
223
253
 
224
254
  # Loads all patients with an outcome of transferred out or
225
255
  # treatment stopped into temp_patient_outcomes table.
226
- def load_patients_who_stopped_treatment
227
- ActiveRecord::Base.connection.execute <<~SQL
228
- INSERT INTO cdr_temp_patient_outcomes PARTITION (p#{location})
229
- SELECT patients.patient_id,
230
- patients.cum_outcome,
231
- patients.outcome_date, patients.site_id, 2
232
- FROM cdr_temp_current_state AS patients
233
- WHERE (patients.patient_id) NOT IN (SELECT patient_id FROM cdr_temp_patient_outcomes PARTITION (p#{location}) WHERE step = 1)
256
+ def load_patients_who_stopped_treatment(start: false)
257
+ ActiveRecord::Base.connection.execute <<~SQL
258
+ INSERT INTO cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location})
259
+ SELECT patients.patient_id,patients.cum_outcome,patients.outcome_date, #{location}, 2
260
+ FROM cdr_temp_current_state#{start ? '_start' : ''} PARTITION (p#{location}) AS patients
261
+ WHERE (patients.patient_id) NOT IN (SELECT patient_id FROM cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location}) WHERE step = 1)
234
262
  AND patients.outcomes = 1
235
- AND patients.site_id = #{location}
236
263
  AND patients.state IN (
237
264
  SELECT pws.program_workflow_state_id state
238
265
  FROM program_workflow pw
@@ -247,53 +274,51 @@ module MalawiHivProgramReports
247
274
 
248
275
  # Load all patients without drug orders or have drug orders
249
276
  # without a quantity.
250
- def load_patients_without_drug_orders
251
- ActiveRecord::Base.connection.execute <<~SQL
252
- INSERT INTO cdr_temp_patient_outcomes PARTITION (p#{location})
253
- SELECT patients.patient_id, 'Unknown', NULL, patients.site_id, 3
254
- FROM cdr_temp_cohort_members AS patients
255
- WHERE date_enrolled <= #{end_date} AND site_id = #{location}
256
- AND (patient_id, site_id) NOT IN (SELECT patient_id, site_id FROM cdr_temp_patient_outcomes PARTITION (p#{location}) WHERE step IN (1, 2, 3, 4))
257
- AND (patient_id, site_id) NOT IN (SELECT patient_id, site_id FROM cdr_temp_max_drug_orders PARTITION (p#{location}))
277
+ def load_patients_without_drug_orders(start: false)
278
+ ActiveRecord::Base.connection.execute <<~SQL
279
+ INSERT INTO cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location})
280
+ SELECT patients.patient_id, 'Unknown', NULL, #{location}, 3
281
+ FROM cdr_temp_cohort_members PARTITION (p#{location}) AS patients
282
+ WHERE date_enrolled <= #{end_date}
283
+ AND (patient_id) NOT IN (SELECT patient_id FROM cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location}) WHERE step IN (1, 2, 3, 4))
284
+ AND (patient_id) NOT IN (SELECT patient_id FROM cdr_temp_max_drug_orders#{start ? '_start' : ''} PARTITION (p#{location}))
258
285
  ON DUPLICATE KEY UPDATE cum_outcome = VALUES(cum_outcome), outcome_date = VALUES(outcome_date), step = VALUES(step)
259
286
  SQL
260
287
  end
261
288
 
262
289
  # Loads all patients who are on treatment
263
- def load_patients_on_treatment
264
- ActiveRecord::Base.connection.execute <<~SQL
265
- INSERT INTO cdr_temp_patient_outcomes PARTITION (p#{location})
266
- SELECT patients.patient_id, 'On antiretrovirals', COALESCE(cs.outcome_date, patients.start_date), patients.site_id, 4
267
- FROM cdr_temp_min_auto_expire_date AS patients
268
- LEFT JOIN cdr_temp_current_state AS cs ON cs.patient_id = patients.patient_id AND cs.site_id = patients.site_id
269
- WHERE patients.#{@definition == 'pepfar' ? 'pepfar_defaulter_date' : 'moh_defaulter_date'} > #{end_date}
270
- AND (patients.patient_id) NOT IN (SELECT patient_id FROM cdr_temp_patient_outcomes PARTITION (p#{location}) WHERE step IN (1, 2, 3))
271
- AND patients.site_id = #{location}
290
+ def load_patients_on_treatment(start: false)
291
+ ActiveRecord::Base.connection.execute <<~SQL
292
+ INSERT INTO cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location})
293
+ SELECT patients.patient_id, 'On antiretrovirals', COALESCE(cs.outcome_date, patients.start_date), #{location}, 4
294
+ FROM cdr_temp_min_auto_expire_date#{start ? '_start' : ''} PARTITION (p#{location}) AS patients
295
+ LEFT JOIN cdr_temp_current_state#{start ? '_start' : ''} PARTITION (p#{location}) AS cs ON cs.patient_id = patients.patient_id AND cs.site_id = patients.site_id
296
+ WHERE patients.#{definition == 'pepfar' ? 'pepfar_defaulter_date' : 'moh_defaulter_date'} > #{end_date}
297
+ AND (patients.patient_id) NOT IN (SELECT patient_id FROM cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location}) WHERE step IN (1, 2, 3))
272
298
  ON DUPLICATE KEY UPDATE cum_outcome = VALUES(cum_outcome), outcome_date = VALUES(outcome_date), step = VALUES(step)
273
299
  SQL
274
300
  end
275
301
 
276
- def load_without_clinical_contact
302
+ def load_without_clinical_contact(start: false)
277
303
  ActiveRecord::Base.connection.execute <<~SQL
278
- INSERT INTO cdr_temp_patient_outcomes PARTITION (p#{location})
279
- SELECT patients.patient_id, 'Defaulted', patients.#{@definition == 'pepfar' ? 'pepfar_defaulter_date' : 'moh_defaulter_date'}, patients.site_id, 5
280
- FROM cdr_temp_current_medication AS patients
281
- LEFT JOIN cdr_temp_current_state AS cs ON cs.patient_id = patients.patient_id AND cs.site_id = patients.site_id#{' '}
282
- WHERE patients.#{@definition == 'pepfar' ? 'pepfar_defaulter_date' : 'moh_defaulter_date'} <= #{end_date}
283
- AND (patients.patient_id) NOT IN (SELECT patient_id FROM cdr_temp_patient_outcomes PARTITION (p#{location}) WHERE step IN (1, 2, 3, 4))
284
- AND patients.site_id = #{location}
304
+ INSERT INTO cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location})
305
+ SELECT patients.patient_id, 'Defaulted', patients.#{definition == 'pepfar' ? 'pepfar_defaulter_date' : 'moh_defaulter_date'},#{location}, 5
306
+ FROM cdr_temp_current_medication#{start ? '_start' : ''} PARTITION (p#{location}) AS patients
307
+ LEFT JOIN cdr_temp_current_state#{start ? '_start' : ''} PARTITION (p#{location}) AS cs ON cs.patient_id = patients.patient_id
308
+ WHERE patients.#{definition == 'pepfar' ? 'pepfar_defaulter_date' : 'moh_defaulter_date'} <= #{end_date}
309
+ AND (patients.patient_id) NOT IN (SELECT patient_id FROM cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location}) WHERE step IN (1, 2, 3, 4))
285
310
  ON DUPLICATE KEY UPDATE cum_outcome = VALUES(cum_outcome), outcome_date = VALUES(outcome_date), step = VALUES(step)
286
311
  SQL
287
312
  end
288
313
 
289
314
  # Load defaulters
290
- def load_defaulters
315
+ def load_defaulters(start: false)
291
316
  ActiveRecord::Base.connection.execute <<~SQL
292
- INSERT INTO cdr_temp_patient_outcomes PARTITION (p#{location})
293
- SELECT patient_id, #{patient_outcome_function('patient_id', 'site_id')}, NULL, site_id, 6
294
- FROM cdr_temp_cohort_members
295
- WHERE date_enrolled <= #{end_date} AND site_id = #{location}
296
- AND (patient_id, site_id) NOT IN (SELECT patient_id, site_id FROM cdr_temp_patient_outcomes PARTITION (p#{location}) WHERE step IN (1, 2, 3, 4, 5))
317
+ INSERT INTO cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location})
318
+ SELECT patient_id, #{patient_outcome_function('patient_id', 'site_id')}, NULL, #{location}, 6
319
+ FROM cdr_temp_cohort_members PARTITION (p#{location})
320
+ WHERE date_enrolled <= #{end_date}
321
+ AND (patient_id, site_id) NOT IN (SELECT patient_id, site_id FROM cdr_temp_patient_outcomes#{start ? '_start' : ''} PARTITION (p#{location}) WHERE step IN (1, 2, 3, 4, 5))
297
322
  ON DUPLICATE KEY UPDATE cum_outcome = VALUES(cum_outcome), outcome_date = VALUES(outcome_date), step = VALUES(step)
298
323
  SQL
299
324
  end
@@ -315,14 +340,18 @@ module MalawiHivProgramReports
315
340
  # Table Management Region
316
341
  # ===================================
317
342
  def prepare_tables
318
- create_outcome_table unless check_if_table_exists('cdr_temp_patient_outcomes')
319
- create_tmp_max_drug_orders_table unless check_if_table_exists('cdr_temp_max_drug_orders')
320
- create_tmp_min_auto_expire_date unless check_if_table_exists('cdr_temp_min_auto_expire_date')
321
- drop_tmp_min_auto_expirte_date unless count_table_columns('cdr_temp_min_auto_expire_date') == 6
322
- create_cdr_temp_max_patient_state unless check_if_table_exists('cdr_temp_max_patient_state')
323
- create_temp_current_state unless check_if_table_exists('cdr_temp_current_state')
324
- drop_temp_current_state unless count_table_columns('cdr_temp_current_state') == 7
325
- create_temp_current_medication unless check_if_table_exists('cdr_temp_current_medication')
343
+ [false, true].each do |start|
344
+ create_outcome_table(start:) unless check_if_table_exists("cdr_temp_patient_outcomes#{start ? '_start' : ''}")
345
+ drop_temp_patient_outcome_table(start:) unless count_table_columns("cdr_temp_patient_outcomes#{start ? '_start' : ''}") == 5
346
+ create_tmp_max_drug_orders_table(start:) unless check_if_table_exists("cdr_temp_max_drug_orders#{start ? '_start' : ''}")
347
+ drop_temp_max_drug_orders_table(start:) unless count_table_columns("cdr_temp_max_drug_orders#{start ? '_start' : ''}") == 4
348
+ create_tmp_min_auto_expire_date(start:) unless check_if_table_exists("cdr_temp_min_auto_expire_date#{start ? '_start' : ''}")
349
+ drop_tmp_min_auto_expirte_date(start:) unless count_table_columns("cdr_temp_min_auto_expire_date#{start ? '_start' : ''}") == 6
350
+ create_cdr_temp_max_patient_state(start:) unless check_if_table_exists("cdr_temp_max_patient_state#{start ? '_start' : ''}")
351
+ create_temp_current_state(start:) unless check_if_table_exists("cdr_temp_current_state#{start ? '_start' : ''}")
352
+ drop_temp_current_state(start:) unless count_table_columns("cdr_temp_current_state#{start ? '_start' : ''}") == 7
353
+ create_temp_current_medication(start:) unless check_if_table_exists("cdr_temp_current_medication#{start ? '_start' : ''}")
354
+ end
326
355
  end
327
356
 
328
357
  def check_if_table_exists(table_name)
@@ -345,9 +374,9 @@ module MalawiHivProgramReports
345
374
  result['count'].to_i
346
375
  end
347
376
 
348
- def create_outcome_table
377
+ def create_outcome_table(start: false)
349
378
  ActiveRecord::Base.connection.execute <<~SQL
350
- CREATE TABLE IF NOT EXISTS cdr_temp_patient_outcomes (
379
+ CREATE TABLE IF NOT EXISTS cdr_temp_patient_outcomes#{start ? '_start' : ''} (
351
380
  patient_id INT NOT NULL,
352
381
  cum_outcome VARCHAR(120) NOT NULL,
353
382
  outcome_date DATE DEFAULT NULL,
@@ -357,43 +386,56 @@ module MalawiHivProgramReports
357
386
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
358
387
  PARTITION BY LIST(site_id) (#{partition_by_site})
359
388
  SQL
360
- create_outcome_indexes
389
+ create_outcome_indexes(start:)
361
390
  end
362
391
 
363
- def create_outcome_indexes
392
+ def drop_temp_patient_outcome_table(start: false)
393
+ ActiveRecord::Base.connection.execute <<~SQL
394
+ DROP TABLE IF EXISTS cdr_temp_patient_outcomes#{start ? '_start' : ''}
395
+ SQL
396
+ create_outcome_table(start:)
397
+ end
398
+
399
+ def create_outcome_indexes(start: false)
364
400
  ActiveRecord::Base.connection.execute <<~SQL
365
- CREATE INDEX idx_outcome ON cdr_temp_patient_outcomes (cum_outcome)
401
+ CREATE INDEX idx_outcome#{start ? '_start' : ''} ON cdr_temp_patient_outcomes#{start ? '_start' : ''} (cum_outcome)
366
402
  SQL
367
403
  ActiveRecord::Base.connection.execute <<~SQL
368
- CREATE INDEX idx_out_date ON cdr_temp_patient_outcomes (outcome_date)
404
+ CREATE INDEX idx_out_date#{start ? '_start' : ''} ON cdr_temp_patient_outcomes#{start ? '_start' : ''} (outcome_date)
369
405
  SQL
370
406
  ActiveRecord::Base.connection.execute <<~SQL
371
- CREATE INDEX idx_out_step ON cdr_temp_patient_outcomes (step)
407
+ CREATE INDEX idx_out_step#{start ? '_start' : ''} ON cdr_temp_patient_outcomes#{start ? '_start' : ''} (step)
372
408
  SQL
373
409
  end
374
410
 
375
- def create_tmp_max_drug_orders_table
411
+ def drop_temp_max_drug_orders_table(start: false)
412
+ ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS cdr_temp_max_drug_orders#{start ? '_start' : ''}")
413
+ create_tmp_max_drug_orders_table(start:)
414
+ end
415
+
416
+ def create_tmp_max_drug_orders_table(start: false)
376
417
  ActiveRecord::Base.connection.execute <<~SQL
377
- CREATE TABLE IF NOT EXISTS cdr_temp_max_drug_orders (
418
+ CREATE TABLE IF NOT EXISTS cdr_temp_max_drug_orders#{start ? '_start' : ''} (
378
419
  patient_id INT NOT NULL,
379
420
  site_id INT NOT NULL,
380
421
  start_date DATETIME DEFAULT NULL,
422
+ min_order_date DATETIME DEFAULT NULL,
381
423
  PRIMARY KEY (patient_id, site_id)
382
424
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
383
425
  PARTITION BY LIST(site_id) (#{partition_by_site})
384
426
  SQL
385
- create_max_drug_orders_indexes
427
+ create_max_drug_orders_indexes(start:)
386
428
  end
387
429
 
388
- def create_max_drug_orders_indexes
430
+ def create_max_drug_orders_indexes(start: false)
389
431
  ActiveRecord::Base.connection.execute <<~SQL
390
- CREATE INDEX idx_max_orders ON cdr_temp_max_drug_orders (start_date)
432
+ CREATE INDEX idx_max_orders#{start ? '_start' : ''} ON cdr_temp_max_drug_orders#{start ? '_start' : ''} (start_date)
391
433
  SQL
392
434
  end
393
435
 
394
- def create_tmp_min_auto_expire_date
436
+ def create_tmp_min_auto_expire_date(start: false)
395
437
  ActiveRecord::Base.connection.execute <<~SQL
396
- CREATE TABLE IF NOT EXISTS cdr_temp_min_auto_expire_date (
438
+ CREATE TABLE IF NOT EXISTS cdr_temp_min_auto_expire_date#{start ? '_start' : ''} (
397
439
  patient_id INT NOT NULL,
398
440
  site_id INT NOT NULL,
399
441
  start_date DATE DEFAULT NULL,
@@ -404,24 +446,24 @@ module MalawiHivProgramReports
404
446
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
405
447
  PARTITION BY LIST(site_id) (#{partition_by_site})
406
448
  SQL
407
- create_min_auto_expire_date_indexes
449
+ create_min_auto_expire_date_indexes(start:)
408
450
  end
409
451
 
410
- def create_min_auto_expire_date_indexes
452
+ def create_min_auto_expire_date_indexes(start: false)
411
453
  ActiveRecord::Base.connection.execute <<~SQL
412
- CREATE INDEX idx_min_auto_expire_date ON temp_min_auto_expire_date (auto_expire_date)
454
+ CREATE INDEX idx_min_auto_expire_date#{start ? '_start' : ''} ON temp_min_auto_expire_date#{start ? '_start' : ''} (auto_expire_date)
413
455
  SQL
414
456
  ActiveRecord::Base.connection.execute <<~SQL
415
- CREATE INDEX idx_min_pepfar ON temp_min_auto_expire_date (pepfar_defaulter_date)
457
+ CREATE INDEX idx_min_pepfar#{start ? '_start' : ''} ON temp_min_auto_expire_date#{start ? '_start' : ''} (pepfar_defaulter_date)
416
458
  SQL
417
459
  ActiveRecord::Base.connection.execute <<~SQL
418
- CREATE INDEX idx_min_moh ON temp_min_auto_expire_date (moh_defaulter_date)
460
+ CREATE INDEX idx_min_moh#{start ? '_start' : ''} ON temp_min_auto_expire_date#{start ? '_start' : ''} (moh_defaulter_date)
419
461
  SQL
420
462
  end
421
463
 
422
- def create_cdr_temp_max_patient_state
464
+ def create_cdr_temp_max_patient_state(start: false)
423
465
  ActiveRecord::Base.connection.execute <<~SQL
424
- CREATE TABLE IF NOT EXISTS cdr_temp_max_patient_state (
466
+ CREATE TABLE IF NOT EXISTS cdr_temp_max_patient_state#{start ? '_start' : ''}(
425
467
  patient_id INT NOT NULL,
426
468
  site_id INT NOT NULL,
427
469
  start_date VARCHAR(15) DEFAULT NULL,
@@ -429,18 +471,18 @@ module MalawiHivProgramReports
429
471
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
430
472
  PARTITION BY LIST(site_id) (#{partition_by_site})
431
473
  SQL
432
- create_max_patient_state_indexes
474
+ create_max_patient_state_indexes(start:)
433
475
  end
434
476
 
435
- def create_max_patient_state_indexes
477
+ def create_max_patient_state_indexes(start: false)
436
478
  ActiveRecord::Base.connection.execute <<~SQL
437
- CREATE INDEX idx_max_patient_state ON cdr_temp_max_patient_state (start_date)
479
+ CREATE INDEX idx_max_patient_state#{start ? '_start' : ''} ON cdr_temp_max_patient_state#{start ? '_start' : ''} (start_date)
438
480
  SQL
439
481
  end
440
482
 
441
- def create_temp_current_state
483
+ def create_temp_current_state(start: false)
442
484
  ActiveRecord::Base.connection.execute <<~SQL
443
- CREATE TABLE IF NOT EXISTS cdr_temp_current_state(
485
+ CREATE TABLE IF NOT EXISTS cdr_temp_current_state#{start ? '_start' : ''}(
444
486
  patient_id INT NOT NULL,
445
487
  site_id INT NOT NULL,
446
488
  cum_outcome VARCHAR(120) NOT NULL,
@@ -452,24 +494,24 @@ module MalawiHivProgramReports
452
494
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
453
495
  PARTITION BY LIST(site_id) (#{partition_by_site})
454
496
  SQL
455
- create_current_state_index
497
+ create_current_state_index(start:)
456
498
  end
457
499
 
458
- def create_current_state_index
500
+ def create_current_state_index(start: false)
459
501
  ActiveRecord::Base.connection.execute <<~SQL
460
- CREATE INDEX idx_state_name ON cdr_temp_current_state (cum_outcome)
502
+ CREATE INDEX idx_state_name#{start ? '_start' : ''} ON cdr_temp_current_state#{start ? '_start' : ''} (cum_outcome)
461
503
  SQL
462
504
  ActiveRecord::Base.connection.execute <<~SQL
463
- CREATE INDEX idx_state_id ON cdr_temp_current_state (state)
505
+ CREATE INDEX idx_state_id#{start ? '_start' : ''} ON cdr_temp_current_state#{start ? '_start' : ''} (state)
464
506
  SQL
465
507
  ActiveRecord::Base.connection.execute <<~SQL
466
- CREATE INDEX idx_state_count ON cdr_temp_current_state (outcomes)
508
+ CREATE INDEX idx_state_count#{start ? '_start' : ''} ON cdr_temp_current_state#{start ? '_start' : ''} (outcomes)
467
509
  SQL
468
510
  end
469
511
 
470
- def create_temp_current_medication
512
+ def create_temp_current_medication(start: false)
471
513
  ActiveRecord::Base.connection.execute <<~SQL
472
- CREATE TABLE IF NOT EXISTS cdr_temp_current_medication(
514
+ CREATE TABLE IF NOT EXISTS cdr_temp_current_medication#{start ? '_start' : ''}(
473
515
  patient_id INT NOT NULL,
474
516
  site_id INT NOT NULL,
475
517
  concept_id INT NOT NULL,
@@ -485,40 +527,40 @@ module MalawiHivProgramReports
485
527
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
486
528
  PARTITION BY LIST(site_id) (#{partition_by_site})
487
529
  SQL
488
- craete_tmp_current_med_index
530
+ create_tmp_current_med_index(start:)
489
531
  end
490
532
 
491
- def craete_tmp_current_med_index
533
+ def create_tmp_current_med_index(start: false)
492
534
  ActiveRecord::Base.connection.execute <<~SQL
493
- CREATE INDEX idx_cm_concept ON cdr_temp_current_medication (concept_id)
535
+ CREATE INDEX idx_cm_concept#{start ? '_start' : ''} ON cdr_temp_current_medication#{start ? '_start' : ''} (concept_id)
494
536
  SQL
495
537
  ActiveRecord::Base.connection.execute <<~SQL
496
- CREATE INDEX idx_cm_drug ON cdr_temp_current_medication (drug_id)
538
+ CREATE INDEX idx_cm_drug#{start ? '_start' : ''} ON cdr_temp_current_medication#{start ? '_start' : ''} (drug_id)
497
539
  SQL
498
540
  ActiveRecord::Base.connection.execute <<~SQL
499
- CREATE INDEX idx_cm_date ON cdr_temp_current_medication (start_date)
541
+ CREATE INDEX idx_cm_date#{start ? '_start' : ''} ON cdr_temp_current_medication#{start ? '_start' : ''} (start_date)
500
542
  SQL
501
543
  ActiveRecord::Base.connection.execute <<~SQL
502
- CREATE INDEX idx_cm_pepfar ON cdr_temp_current_medication (pepfar_defaulter_date)
544
+ CREATE INDEX idx_cm_pepfar#{start ? '_start' : ''} ON cdr_temp_current_medication#{start ? '_start' : ''} (pepfar_defaulter_date)
503
545
  SQL
504
546
  ActiveRecord::Base.connection.execute <<~SQL
505
- CREATE INDEX idx_cm_moh ON cdr_temp_current_medication (moh_defaulter_date)
547
+ CREATE INDEX idx_cm_moh#{start ? '_start' : ''} ON cdr_temp_current_medication#{start ? '_start' : ''} (moh_defaulter_date)
506
548
  SQL
507
549
  end
508
550
 
509
- def drop_tmp_min_auto_expirte_date
510
- ActiveRecord::Base.connection.execute 'DROP TABLE cdr_temp_min_auto_expire_date'
511
- create_tmp_min_auto_expire_date
551
+ def drop_tmp_min_auto_expirte_date(start: false)
552
+ ActiveRecord::Base.connection.execute "DROP TABLE cdr_temp_min_auto_expire_date#{start ? '_start' : ''}"
553
+ create_tmp_min_auto_expire_date(start:)
512
554
  end
513
555
 
514
- def drop_temp_current_state
515
- ActiveRecord::Base.connection.execute 'DROP TABLE cdr_temp_current_state'
516
- create_temp_current_state
556
+ def drop_temp_current_state(start: false)
557
+ ActiveRecord::Base.connection.execute "DROP TABLE cdr_temp_current_state#{start ? '_start' : ''}"
558
+ create_temp_current_state(start:)
517
559
  end
518
560
 
519
- def update_steps
561
+ def update_steps(start: false, portion: false)
520
562
  ActiveRecord::Base.connection.execute <<~SQL
521
- UPDATE cdr_temp_patient_outcomes SET step = 0 WHERE step > 0 AND site_id = #{location}
563
+ UPDATE cdr_temp_patient_outcomes#{start ? '_start' : ''} SET step = 0 WHERE step >= #{portion ? 4 : 1 } AND site_id = #{location}
522
564
  SQL
523
565
  end
524
566
 
@@ -526,25 +568,26 @@ module MalawiHivProgramReports
526
568
  @arv_drug ||= ::Drug.arv_drugs.map(&:drug_id).join(',')
527
569
  end
528
570
 
529
- def clear_tables
571
+ def clear_tables(start: false)
530
572
  # we truncate if @locations is empty otherwise we only clean the specifieds
531
573
  if location.empty?
532
- ActiveRecord::Base.connection.execute('TRUNCATE cdr_temp_patient_outcomes')
533
- ActiveRecord::Base.connection.execute('TRUNCATE cdr_temp_max_drug_orders')
534
- ActiveRecord::Base.connection.execute('TRUNCATE cdr_temp_min_auto_expire_date')
535
- ActiveRecord::Base.connection.execute('TRUNCATE cdr_temp_max_patient_state')
536
- ActiveRecord::Base.connection.execute('TRUNCATE cdr_temp_current_state')
537
- ActiveRecord::Base.connection.execute('TRUNCATE cdr_temp_current_medication')
574
+ ActiveRecord::Base.connection.execute("TRUNCATE cdr_temp_patient_outcomes#{start ? '_start' : ''}")
575
+ ActiveRecord::Base.connection.execute("TRUNCATE cdr_temp_max_drug_orders#{start ? '_start' : ''}")
576
+ ActiveRecord::Base.connection.execute("TRUNCATE cdr_temp_min_auto_expire_date#{start ? '_start' : ''}")
577
+ ActiveRecord::Base.connection.execute("TRUNCATE cdr_temp_max_patient_state#{start ? '_start' : ''}")
578
+ ActiveRecord::Base.connection.execute("TRUNCATE cdr_temp_current_state#{start ? '_start' : ''}")
579
+ ActiveRecord::Base.connection.execute("TRUNCATE cdr_temp_current_medication#{start ? '_start' : ''}")
538
580
  else
539
- ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_patient_outcomes WHERE site_id = #{location}")
540
- ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_max_drug_orders WHERE site_id = #{location}")
541
- ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_min_auto_expire_date WHERE site_id = #{location}")
542
- ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_max_patient_state WHERE site_id = #{location}")
543
- ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_current_state WHERE site_id = #{location}")
544
- ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_current_medication WHERE site_id = #{location}")
581
+ ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_patient_outcomes#{start ? '_start' : ''} WHERE site_id = #{location}")
582
+ ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_max_drug_orders#{start ? '_start' : ''} WHERE site_id = #{location}")
583
+ ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_min_auto_expire_date#{start ? '_start' : ''} WHERE site_id = #{location}")
584
+ ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_max_patient_state#{start ? '_start' : ''} WHERE site_id = #{location}")
585
+ ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_current_state#{start ? '_start' : ''} WHERE site_id = #{location}")
586
+ ActiveRecord::Base.connection.execute("DELETE FROM cdr_temp_current_medication#{start ? '_start' : ''} WHERE site_id = #{location}")
545
587
  end
546
588
  end
547
589
  end
548
590
  # rubocop:enable Metrics/ClassLength
591
+ # rubocop:enable Metrics/MethodLength
549
592
  end
550
593
  end