malawi_hiv_program_reports 1.0.12 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/services/malawi_hiv_program_reports/adapters/moh/custom.rb +3 -2
- data/app/services/malawi_hiv_program_reports/cohort/outcomes.rb +58 -29
- data/app/services/malawi_hiv_program_reports/cohort/regimens.rb +4 -20
- data/app/services/malawi_hiv_program_reports/moh/cohort_builder.rb +184 -221
- data/lib/malawi_hiv_program_reports/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e822549d8adf92be3c36169ba9b0f279b8e36837e237dff82bf7a06f1eed7a6a
|
4
|
+
data.tar.gz: df4680fed4a17a65e077a9648fd06d752a816b8845c80141a99d9e895eb5bcee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f948b554218cf4420b06a37a98028bbceebb06aad04a61d3cce9651aadfbc429dc6603d853e03d51eb5bbe51688b4bfd7b704301c4f53c99031985dfb1cca53b
|
7
|
+
data.tar.gz: 1214999f3ee1fbb72287e31f634e28aa650ec6a9ba9b5cedb29c38416f7a53cedd0adf4d521bada6a1d562b1054a9087e3e43174752d8fbf7cf6939889a1854a
|
@@ -86,11 +86,12 @@ module MalawiHivProgramReports
|
|
86
86
|
ActiveRecord::Base.connection.execute <<-SQL
|
87
87
|
CREATE TABLE temp_register_start_date (
|
88
88
|
patient_id INT NOT NULL,
|
89
|
-
site_id INT
|
89
|
+
site_id INT NOT NULL,
|
90
90
|
start_date DATE NOT NULL,
|
91
|
-
PRIMARY KEY (patient_id)
|
91
|
+
PRIMARY KEY (patient_id, site_id)
|
92
92
|
) #{adapter == 'mysql2' ? 'ENGINE=InnoDB DEFAULT CHARSET=utf8' : ''};
|
93
93
|
SQL
|
94
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX trsd_date ON temp_register_start_date (start_date)'
|
94
95
|
end
|
95
96
|
|
96
97
|
def exe_temp_order_details_table(adapter:)
|
@@ -19,6 +19,8 @@ module MalawiHivProgramReports
|
|
19
19
|
|
20
20
|
def update_cummulative_outcomes
|
21
21
|
initialize_table
|
22
|
+
create_tmp_max_drug_orders
|
23
|
+
create_tmp_min_auto_expire_date
|
22
24
|
|
23
25
|
# HIC SUNT DRACONIS: The order of the operations below matters,
|
24
26
|
# do not change it unless you know what you are doing!!!
|
@@ -208,7 +210,7 @@ module MalawiHivProgramReports
|
|
208
210
|
AND voided = 0 #{site_manager(operator: 'AND', column: 'patient_state.site_id', location: @location)}
|
209
211
|
)
|
210
212
|
AND patients.patient_id NOT IN (SELECT patient_id FROM temp_patient_outcomes #{site_manager(operator: 'WHERE', column: 'patient_program.site_id', location: @location)} )
|
211
|
-
GROUP BY patients.patient_id
|
213
|
+
GROUP BY patients.patient_id HAVING cum_outcome = 'Defaulted'
|
212
214
|
SQL
|
213
215
|
end
|
214
216
|
|
@@ -237,6 +239,59 @@ module MalawiHivProgramReports
|
|
237
239
|
SQL
|
238
240
|
end
|
239
241
|
|
242
|
+
# rubocop:disable Metrics/MethodLength
|
243
|
+
def create_tmp_max_drug_orders
|
244
|
+
date = ActiveRecord::Base.connection.quote(end_date)
|
245
|
+
ActiveRecord::Base.connection.execute 'DROP TABLE IF EXISTS tmp_max_drug_orders'
|
246
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
247
|
+
CREATE TABLE tmp_max_drug_orders(
|
248
|
+
patient_id INT(11) PRIMARY KEY,
|
249
|
+
start_date DATETIME NOT NULL,
|
250
|
+
site_id INT NOT NULL
|
251
|
+
)
|
252
|
+
SQL
|
253
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX idx_tmp_max_drug_orders ON tmp_max_drug_orders (patient_id, start_date)'
|
254
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX tmdo_site_id ON tmp_max_drug_orders (site_id)'
|
255
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
256
|
+
INSERT INTO tmp_max_drug_orders
|
257
|
+
SELECT o.patient_id, MAX(o.start_date) AS start_date, o.site_id
|
258
|
+
FROM orders o
|
259
|
+
INNER JOIN temp_earliest_start_date tesd ON tesd.patient_id = o.patient_id AND tesd.site_id = o.site_id #{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
260
|
+
INNER JOIN drug_order ON o.order_id = drug_order.order_id AND quantity > 0 #{site_manager(operator: 'AND', column: 'drug_order.site_id', location: @location)}
|
261
|
+
INNER JOIN arv_drug ad ON ad.drug_id = drug_order.drug_inventory_id
|
262
|
+
WHERE o.order_type_id = #{drug_order_type.order_type_id}
|
263
|
+
AND o.start_date < (DATE(#{date}) + INTERVAL 1 DAY)
|
264
|
+
AND o.voided = 0 #{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
265
|
+
AND o.patient_id NOT IN (SELECT patient_id FROM temp_patient_outcomes #{site_manager(operator: 'WHERE', column: 'site_id', location: @location)})
|
266
|
+
GROUP BY o.patient_id
|
267
|
+
SQL
|
268
|
+
end
|
269
|
+
|
270
|
+
def create_tmp_min_auto_expire_date
|
271
|
+
ActiveRecord::Base.connection.execute 'DROP TABLE IF EXISTS tmp_min_auto_expire_date'
|
272
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
273
|
+
CREATE TABLE tmp_min_auto_expire_date(
|
274
|
+
patient_id INT(11) PRIMARY KEY,
|
275
|
+
auto_expire_date DATETIME NOT NULL,
|
276
|
+
site_id INT NOT NULL
|
277
|
+
)
|
278
|
+
SQL
|
279
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX idx_tmp_min_auto_expire_date ON tmp_min_auto_expire_date (patient_id, auto_expire_date)'
|
280
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX tmaed_site_id ON tmp_min_auto_expire_date (site_id)'
|
281
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
282
|
+
INSERT INTO tmp_min_auto_expire_date
|
283
|
+
SELECT patient_id, MIN(auto_expire_date) AS auto_expire_date, o.site_id
|
284
|
+
FROM orders o
|
285
|
+
INNER JOIN tmp_max_drug_orders USING (patient_id, start_date, site_id)
|
286
|
+
INNER JOIN drug_order ON o.order_id = drug_order.order_id AND quantity > 0 #{site_manager(operator: 'AND', column: 'drug_order.site_id', location: @location)}
|
287
|
+
INNER JOIN arv_drug ad ON ad.drug_id = drug_order.drug_inventory_id
|
288
|
+
WHERE o.order_type_id = #{drug_order_type.order_type_id}
|
289
|
+
AND o.voided = 0 #{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
290
|
+
GROUP BY patient_id HAVING auto_expire_date IS NOT NULL
|
291
|
+
SQL
|
292
|
+
end
|
293
|
+
# rubocop:enable Metrics/MethodLength
|
294
|
+
|
240
295
|
# Loads all patients who are on treatment
|
241
296
|
def load_patients_on_treatment
|
242
297
|
date = ActiveRecord::Base.connection.quote(end_date)
|
@@ -270,35 +325,9 @@ module MalawiHivProgramReports
|
|
270
325
|
ARV dispensations. In other words filter out any `on ARVs` states whose
|
271
326
|
dispensation's may have been voided or states that were created manually
|
272
327
|
without any drugs being dispensed. */
|
273
|
-
INNER JOIN
|
274
|
-
SELECT orders.patient_id, MIN(orders.auto_expire_date) AS auto_expire_date
|
275
|
-
FROM orders
|
276
|
-
INNER JOIN drug_order ON orders.order_id = drug_order.order_id #{site_manager(operator: 'AND', column: 'drug_order.site_id', location: @location)}
|
277
|
-
INNER JOIN (
|
278
|
-
SELECT patient_id, MAX(start_date) AS start_date
|
279
|
-
FROM orders
|
280
|
-
INNER JOIN drug_order ON orders.order_id = drug_order.order_id #{site_manager(operator: 'AND', column: 'drug_order.site_id', location: @location)} AND drug_order.quantity > 0
|
281
|
-
WHERE order_type_id = #{drug_order_type.order_type_id}
|
282
|
-
AND concept_id IN (#{arv_drugs_concept_set.to_sql})
|
283
|
-
AND orders.start_date < #{interval_manager(date:, value: 1, interval: 'DAY', operator: '+')}
|
284
|
-
AND voided = 0 #{site_manager(operator: 'AND', column: 'orders.site_id', location: @location)}
|
285
|
-
AND patient_id IN (SELECT patient_id FROM temp_earliest_start_date #{site_manager(operator: 'WHERE', column: 'site_id', location: @location)} )
|
286
|
-
AND patient_id NOT IN (SELECT patient_id FROM temp_patient_outcomes #{site_manager(operator: 'WHERE', column: 'site_id', location: @location)} )
|
287
|
-
GROUP BY patient_id
|
288
|
-
) AS max_drug_orders
|
289
|
-
ON max_drug_orders.patient_id = orders.patient_id
|
290
|
-
AND max_drug_orders.start_date = orders.start_date #{site_manager(operator: 'AND', column: 'orders.site_id', location: @location)}
|
291
|
-
WHERE order_type_id = #{drug_order_type.order_type_id}
|
292
|
-
AND concept_id IN (#{arv_drugs_concept_set.to_sql})
|
293
|
-
AND orders.start_date < #{interval_manager(date:, value: 1, interval: 'DAY', operator: '+')}
|
294
|
-
AND quantity > 0
|
295
|
-
AND voided = 0 #{site_manager(operator: 'AND', column: 'orders.site_id', location: @location)}
|
296
|
-
AND orders.patient_id IN (SELECT patient_id FROM temp_earliest_start_date #{site_manager(operator: 'WHERE', column: 'site_id', location: @location)})
|
297
|
-
AND orders.patient_id NOT IN (SELECT patient_id FROM temp_patient_outcomes #{site_manager(operator: 'WHERE', column: 'site_id', location: @location)})
|
298
|
-
GROUP BY orders.patient_id
|
299
|
-
) AS first_order_to_expire
|
328
|
+
INNER JOIN tmp_min_auto_expire_date AS first_order_to_expire
|
300
329
|
ON (first_order_to_expire.auto_expire_date >= #{date} OR #{timestampdiff_manager(date1: 'DATE(first_order_to_expire.auto_expire_date)', date2: date, interval: 'DAY')} <= #{@definition == 'pepfar' ? 28 : 56})
|
301
|
-
AND first_order_to_expire.patient_id = patient_program.patient_id #{site_manager(operator: 'AND', column: 'patient_program.site_id', location: @location)}
|
330
|
+
AND first_order_to_expire.patient_id = patient_program.patient_id #{site_manager(operator: 'AND', column: 'first_order_to_expire.site_id', location: @location)} #{site_manager(operator: 'AND', column: 'patient_program.site_id', location: @location)}
|
302
331
|
WHERE patients.date_enrolled <= #{date} #{site_manager(operator: 'AND', column: 'patients.site_id', location: @location)}
|
303
332
|
AND patients.patient_id NOT IN (SELECT patient_id FROM temp_patient_outcomes #{site_manager(operator: 'WHERE', column: 'site_id', location: @location)} )
|
304
333
|
GROUP BY patients.patient_id #{@adapter == 'mysql2' ? '' : ',patient_state.start_date'}
|
@@ -9,7 +9,7 @@ module MalawiHivProgramReports
|
|
9
9
|
def patient_regimens(date, location)
|
10
10
|
@location = location
|
11
11
|
@adapter = ActiveRecord::Base.connection.adapter_name.downcase
|
12
|
-
|
12
|
+
ActiveRecord::Base.connection.quote(date)
|
13
13
|
|
14
14
|
ActiveRecord::Base.connection.select_all <<~SQL
|
15
15
|
SELECT prescriptions.patient_id,
|
@@ -19,33 +19,17 @@ module MalawiHivProgramReports
|
|
19
19
|
FROM (
|
20
20
|
SELECT orders.patient_id,
|
21
21
|
#{@adapter == 'mysql2' ? 'GROUP_CONCAT(DISTINCT drug_order.drug_inventory_id ORDER BY drug_order.drug_inventory_id ASC) AS drugs,' : "(SELECT STRING_AGG(drug_inventory_id::VARCHAR, ',') FROM (SELECT DISTINCT drug_order.drug_inventory_id FROM drug_order ORDER BY drug_order.drug_inventory_id ASC) AS subquery) AS drugs,"}
|
22
|
-
|
22
|
+
DATE(tmdo.start_date) prescription_date
|
23
23
|
FROM temp_patient_outcomes AS outcomes
|
24
|
+
INNER JOIN tmp_max_drug_orders tmdo ON tmdo.patient_id = outcomes.patient_id AND outcomes.cum_outcome = 'On antiretrovirals' #{site_manager(operator: 'AND', column: 'tmdo.site_id', location: @location)}
|
24
25
|
INNER JOIN orders
|
25
26
|
ON orders.patient_id = outcomes.patient_id
|
26
27
|
AND orders.concept_id IN (#{arv_drugs_concept_set.to_sql})
|
27
28
|
AND orders.voided = 0 #{site_manager(operator: 'AND', column: 'orders.site_id', location: @location)}
|
29
|
+
AND DATE(orders.start_date) = DATE(tmdo.start_date)
|
28
30
|
INNER JOIN drug_order
|
29
31
|
ON drug_order.order_id = orders.order_id AND drug_order.quantity > 0 #{site_manager(operator: 'AND', column: 'drug_order.site_id', location: @location)}
|
30
32
|
/* Only select drugs prescribed on the last prescription day */
|
31
|
-
INNER JOIN (
|
32
|
-
SELECT patient_id, DATE(MAX(start_date)) AS prescription_date
|
33
|
-
FROM orders
|
34
|
-
INNER JOIN drug_order
|
35
|
-
ON drug_order.order_id = orders.order_id
|
36
|
-
AND drug_order.quantity > 0 #{site_manager(operator: 'AND', column: 'drug_order.site_id', location: @location)}
|
37
|
-
WHERE orders.voided = 0 #{site_manager(operator: 'AND', column: 'orders.site_id', location: @location)}
|
38
|
-
AND orders.concept_id IN (#{arv_drugs_concept_set.to_sql})
|
39
|
-
AND orders.start_date < #{interval_manager(date:, value: 1, interval: 'DAY', operator: '+')}
|
40
|
-
AND orders.patient_id IN (
|
41
|
-
SELECT patient_id FROM temp_patient_outcomes WHERE cum_outcome = 'On antiretrovirals' #{site_manager(operator: 'AND', column: 'site_id', location: @location)}
|
42
|
-
)
|
43
|
-
GROUP BY orders.patient_id
|
44
|
-
) AS recent_prescription
|
45
|
-
ON recent_prescription.patient_id = orders.patient_id
|
46
|
-
AND orders.start_date
|
47
|
-
BETWEEN recent_prescription.prescription_date
|
48
|
-
AND #{interval_manager(date: 'recent_prescription.prescription_date', value: 1, interval: 'DAY', operator: '+')}
|
49
33
|
GROUP BY orders.patient_id #{@adapter == 'mysql2' ? '' : ', recent_prescription.prescription_date'}
|
50
34
|
) AS prescriptions
|
51
35
|
LEFT JOIN (
|
@@ -29,9 +29,11 @@ module MalawiHivProgramReports
|
|
29
29
|
drop_temp_register_start_date_table
|
30
30
|
drop_temp_other_patient_types
|
31
31
|
drop_temp_order_details
|
32
|
+
drop_art_start_date
|
32
33
|
create_temp_other_patient_types(end_date)
|
33
34
|
create_temp_register_start_date_table(end_date)
|
34
35
|
create_temp_order_details(end_date)
|
36
|
+
create_art_start_date(end_date)
|
35
37
|
load_data_into_temp_earliest_start_date(end_date.to_date, occupation)
|
36
38
|
update_cum_outcome(end_date)
|
37
39
|
end
|
@@ -43,9 +45,11 @@ module MalawiHivProgramReports
|
|
43
45
|
drop_temp_register_start_date_table
|
44
46
|
drop_temp_other_patient_types
|
45
47
|
drop_temp_order_details
|
48
|
+
drop_art_start_date
|
46
49
|
create_temp_other_patient_types(end_date)
|
47
50
|
create_temp_register_start_date_table(end_date)
|
48
51
|
create_temp_order_details(end_date)
|
52
|
+
create_art_start_date(end_date)
|
49
53
|
load_data_into_temp_earliest_start_date(end_date.to_date, occupation)
|
50
54
|
|
51
55
|
# create_tmp_patient_table_2(end_date)
|
@@ -92,7 +96,7 @@ module MalawiHivProgramReports
|
|
92
96
|
cohort_struct.quarterly_all_males = males(quarter_start_date, end_date)
|
93
97
|
|
94
98
|
# Pregnant females (all ages)
|
95
|
-
create_temp_pregnant_obs(
|
99
|
+
create_temp_pregnant_obs(cum_start_date, end_date)
|
96
100
|
cohort_struct.pregnant_females_all_ages = pregnant_females_all_ages(start_date, end_date)
|
97
101
|
cohort_struct.cum_pregnant_females_all_ages = pregnant_females_all_ages(cum_start_date, end_date)
|
98
102
|
cohort_struct.quarterly_pregnant_females_all_ages = pregnant_females_all_ages(quarter_start_date, end_date)
|
@@ -678,11 +682,11 @@ module MalawiHivProgramReports
|
|
678
682
|
def load_data_into_temp_cohort_members_table(end_date)
|
679
683
|
end_date = ActiveRecord::Base.connection.quote(end_date)
|
680
684
|
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
685
|
+
concept('Type of patient').concept_id
|
686
|
+
concept('New patient').concept_id
|
687
|
+
concept('Drug refill').concept_id
|
688
|
+
concept('External Consultation').concept_id
|
689
|
+
program('HIV program').id
|
686
690
|
|
687
691
|
ActiveRecord::Base.connection.execute <<~SQL
|
688
692
|
INSERT INTO temp_cohort_members
|
@@ -693,7 +697,7 @@ module MalawiHivProgramReports
|
|
693
697
|
person.birthdate,
|
694
698
|
#{@adapter == 'mysql2' ? 'person.birthdate_estimated' : '(CASE WHEN person.birthdate_estimated = 0 THEN false ELSE true END)'} AS birthdate_estimated,
|
695
699
|
person.death_date,
|
696
|
-
person.gender, #{
|
700
|
+
LEFT(person.gender, 1) gender, #{
|
697
701
|
if @adapter == 'mysql2'
|
698
702
|
<<~SQL
|
699
703
|
IF(person.birthdate IS NOT NULL, TIMESTAMPDIFF(YEAR, person.birthdate, DATE(COALESCE(art_start_date_obs.value_datetime, MIN(art_order.start_date)))), NULL) AS age_at_initiation,
|
@@ -720,65 +724,21 @@ module MalawiHivProgramReports
|
|
720
724
|
ORDER BY obs_datetime DESC, date_created DESC LIMIT 1) as reason_for_starting_art,
|
721
725
|
pa.value AS occupation
|
722
726
|
FROM patient_program
|
723
|
-
INNER JOIN person ON person.person_id = patient_program.patient_id #{site_manager(operator: 'AND', column: 'person.site_id', location: @location)}
|
727
|
+
INNER JOIN person ON person.person_id = patient_program.patient_id AND person.voided = 0 #{site_manager(operator: 'AND', column: 'person.site_id', location: @location)}
|
724
728
|
LEFT JOIN (#{current_occupation_query}) pa ON pa.person_id = patient_program.patient_id #{site_manager(operator: 'AND', column: 'pa.site_id', location: @location)}
|
725
729
|
LEFT JOIN patient_state AS outcome
|
726
730
|
ON outcome.patient_program_id = patient_program.patient_program_id #{site_manager(operator: 'AND', column: 'outcome.site_id', location: @location)}
|
727
|
-
LEFT JOIN
|
728
|
-
ON
|
729
|
-
SELECT encounter_type_id FROM encounter_type WHERE LOWER(name) = LOWER('HIV CLINIC REGISTRATION') LIMIT 1
|
730
|
-
)
|
731
|
-
AND clinic_registration_encounter.patient_id = patient_program.patient_id
|
732
|
-
AND clinic_registration_encounter.program_id = patient_program.program_id
|
733
|
-
AND clinic_registration_encounter.encounter_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
734
|
-
AND clinic_registration_encounter.voided = 0 #{site_manager(operator: 'AND', column: 'clinic_registration_encounter.site_id', location: @location)}
|
735
|
-
LEFT JOIN obs AS art_start_date_obs
|
736
|
-
ON art_start_date_obs.concept_id = 2516
|
737
|
-
AND art_start_date_obs.person_id = patient_program.patient_id
|
738
|
-
AND art_start_date_obs.voided = 0 #{site_manager(operator: 'AND', column: 'art_start_date_obs.site_id', location: @location)}
|
739
|
-
AND art_start_date_obs.obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
740
|
-
AND art_start_date_obs.encounter_id = clinic_registration_encounter.encounter_id
|
741
|
-
/* TODO: Re-enable the following condition. Has been removed because LLH and PIH
|
742
|
-
were noted to be dropping patients because of it. Seems these sites may have orders
|
743
|
-
without corresponding encounters. Adding this condition bumps up performance a bit. */
|
744
|
-
/* INNER JOIN encounter AS prescription_encounter
|
745
|
-
ON prescription_encounter.patient_id = patient_program.patient_id
|
746
|
-
AND prescription_encounter.program_id = patient_program.program_id
|
747
|
-
AND prescription_encounter.encounter_datetime < DATE(#{end_date}) + INTERVAL 1 DAY
|
748
|
-
AND prescription_encounter.encounter_type IN (SELECT encounter_type_id FROM encounter_type WHERE name LIKE 'Treatment')
|
749
|
-
AND prescription_encounter.voided = 0
|
750
|
-
LEFT JOIN temp_register_start_date AS patient_type_obs
|
751
|
-
ON patient_type_obs.patient_id = patient_program.patient_id #{site_manager(operator: 'AND', column: 'patient_type_obs.site_id', location: @location)}
|
752
|
-
INNER JOIN orders AS art_order
|
753
|
-
ON art_order.patient_id = patient_program.patient_id
|
754
|
-
-- AND art_order.encounter_id = prescription_encounter.encounter_id
|
755
|
-
AND art_order.concept_id IN (SELECT concept_id FROM concept_set WHERE concept_set = 1085)
|
756
|
-
AND art_order.start_date < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
757
|
-
AND art_order.order_type_id = #{order_type('Drug order').id}
|
758
|
-
AND art_order.start_date >= COALESCE(patient_type_obs.start_date, DATE('1901-01-01'))
|
759
|
-
AND art_order.voided = 0 #{site_manager(operator: 'AND', column: 'art_order.site_id', location: @location)}
|
760
|
-
INNER JOIN drug_order
|
761
|
-
ON drug_order.order_id = art_order.order_id
|
762
|
-
AND drug_order.quantity > 0 #{site_manager(operator: 'AND', column: 'drug_order.site_id', location: @location)} */
|
731
|
+
LEFT JOIN temp_art_start_date AS art_start_date_obs
|
732
|
+
ON art_start_date_obs.patient_id = patient_program.patient_id #{site_manager(operator: 'AND', column: 'art_start_date_obs.site_id', location: @location)}
|
763
733
|
INNER JOIN temp_order_details AS art_order ON art_order.patient_id = patient_program.patient_id #{site_manager(operator: 'AND', column: 'art_order.site_id', location: @location)}
|
734
|
+
AND art_order.start_date <= DATE(#{end_date})
|
764
735
|
WHERE patient_program.voided = 0
|
765
736
|
AND outcome.voided = 0
|
766
737
|
AND patient_program.program_id = 1
|
767
738
|
AND outcome.state = 7
|
768
739
|
AND outcome.start_date IS NOT NULL #{site_manager(operator: 'AND', column: 'patient_program.site_id', location: @location)}
|
769
|
-
/*AND patient_program.patient_id NOT IN (
|
770
|
-
SELECT e.patient_id FROM encounter e
|
771
|
-
LEFT JOIN (SELECT * FROM obs WHERE concept_id = #{type_of_patient_concept} AND voided = 0 AND value_coded = #{new_patient_concept}) AS new_patient ON e.patient_id = new_patient.person_id
|
772
|
-
LEFT JOIN (SELECT * FROM obs WHERE concept_id = #{type_of_patient_concept} AND voided = 0 AND value_coded = #{drug_refill_concept}) AS refill ON e.patient_id = refill.person_id
|
773
|
-
LEFT JOIN (SELECT * FROM obs WHERE concept_id = #{type_of_patient_concept} AND voided = 0 AND value_coded = #{external_concept}) AS external ON e.patient_id = external.person_id
|
774
|
-
WHERE e.program_id = #{program_id} AND (refill.value_coded IS NOT NULL OR external.value_coded IS NOT NULL)
|
775
|
-
AND new_patient.value_coded IS NULL
|
776
|
-
AND e.encounter_datetime < DATE(#{end_date}) + INTERVAL 1 DAY
|
777
|
-
AND e.encounter_type IN (SELECT encounter_type_id FROM encounter_type WHERE name = 'REGISTRATION' AND retired = 0)
|
778
|
-
GROUP BY e.patient_id
|
779
|
-
)*/
|
780
740
|
GROUP by patient_program.patient_id #{@adapter == 'mysql2' ? '' : ',person.birthdate, person.birthdate_estimated, person.death_date, person.gender, pa.value'}
|
781
|
-
HAVING
|
741
|
+
HAVING reason_for_starting_art IS NOT NULL
|
782
742
|
SQL
|
783
743
|
remove_drug_refills_and_external_consultation(end_date)
|
784
744
|
end
|
@@ -858,6 +818,44 @@ module MalawiHivProgramReports
|
|
858
818
|
SQL
|
859
819
|
end
|
860
820
|
|
821
|
+
def drop_art_start_date
|
822
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
823
|
+
DROP TABLE IF EXISTS temp_art_start_date
|
824
|
+
SQL
|
825
|
+
end
|
826
|
+
|
827
|
+
def create_art_start_date(end_date)
|
828
|
+
ActiveRecord::Base.connection.execute <<-SQL
|
829
|
+
CREATE TABLE temp_art_start_date (
|
830
|
+
patient_id INT(11) NOT NULL,
|
831
|
+
value_datetime DATE NOT NULL,
|
832
|
+
site_id INT(11) NOT NULL,
|
833
|
+
PRIMARY KEY (patient_id)
|
834
|
+
)
|
835
|
+
SQL
|
836
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX tasd_date ON temp_art_start_date (value_datetime)'
|
837
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX tasd_site ON temp_art_start_date (site_id)'
|
838
|
+
load_art_start_date(end_date)
|
839
|
+
end
|
840
|
+
|
841
|
+
def load_art_start_date(end_date)
|
842
|
+
ActiveRecord::Base.connection.execute <<-SQL
|
843
|
+
INSERT INTO temp_art_start_date
|
844
|
+
SELECT o.person_id, DATE(MIN(o.value_datetime)) value_datetime, o.site_id
|
845
|
+
FROM encounter e
|
846
|
+
INNER JOIN obs o ON o.encounter_id = e.encounter_id#{' '}
|
847
|
+
AND o.concept_id = 2516#{' '}
|
848
|
+
AND e.encounter_type = 9#{' '}
|
849
|
+
AND e.program_id = 1#{' '}
|
850
|
+
AND e.voided = 0 #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
|
851
|
+
AND e.encounter_datetime < DATE('#{end_date}') + INTERVAL 1 DAY
|
852
|
+
AND o.obs_datetime < (DATE('#{end_date}') + INTERVAL 1 DAY)
|
853
|
+
AND e.voided = 0 #{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
854
|
+
WHERE e.voided = 0 #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
|
855
|
+
GROUP BY o.person_id
|
856
|
+
SQL
|
857
|
+
end
|
858
|
+
|
861
859
|
def create_temp_order_details(end_date)
|
862
860
|
exe_temp_order_details_table(adapter: @adapter)
|
863
861
|
ActiveRecord::Base.connection.execute <<~SQL
|
@@ -1001,19 +999,18 @@ module MalawiHivProgramReports
|
|
1001
999
|
ActiveRecord::Base.connection.execute('CREATE INDEX patient_id_site_id_index ON temp_patient_tb_status (patient_id, site_id)')
|
1002
1000
|
ActiveRecord::Base.connection.execute('CREATE INDEX patient_id_tb_status_index ON temp_patient_tb_status (patient_id, tb_status)')
|
1003
1001
|
|
1002
|
+
prepare_latest_tb_status_table
|
1003
|
+
create_temp_latest_tb_status(end_date)
|
1004
|
+
|
1004
1005
|
ActiveRecord::Base.connection.execute <<~SQL
|
1005
|
-
INSERT INTO temp_patient_tb_status
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
RIGHT JOIN obs ON obs.person_id = o.patient_id #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1010
|
-
WHERE e.date_enrolled <= '#{end_date}' AND obs.obs_datetime <= '#{end_date} 23:59:59'
|
1011
|
-
AND LOWER(cum_outcome) = LOWER('On antiretrovirals') AND obs.voided = 0
|
1006
|
+
INSERT INTO temp_patient_tb_status
|
1007
|
+
SELECT e.person_id, obs.value_coded, e.site_id
|
1008
|
+
FROM temp_latest_tb_status e
|
1009
|
+
INNER JOIN obs ON obs.person_id = e.person_id AND obs.voided = 0
|
1012
1010
|
AND obs.concept_id = 7459 #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
|
1013
|
-
AND obs.obs_datetime = (
|
1014
|
-
|
1015
|
-
|
1016
|
-
) GROUP BY e.patient_id #{@adapter == 'mysql2' ? '' : ', obs.value_coded'}
|
1011
|
+
AND obs.obs_datetime = e.obs_datetime #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1012
|
+
#{site_manager(operator: 'WHERE', column: 'e.site_id', location: @location)}
|
1013
|
+
GROUP BY e.person_id;
|
1017
1014
|
SQL
|
1018
1015
|
end
|
1019
1016
|
|
@@ -1023,6 +1020,34 @@ module MalawiHivProgramReports
|
|
1023
1020
|
|
1024
1021
|
private
|
1025
1022
|
|
1023
|
+
def prepare_latest_tb_status_table
|
1024
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
1025
|
+
CREATE TABLE IF NOT EXISTS temp_latest_tb_status(
|
1026
|
+
person_id INT PRIMARY KEY,
|
1027
|
+
obs_datetime DATETIME,
|
1028
|
+
site_id INT NOT NULL
|
1029
|
+
)
|
1030
|
+
SQL
|
1031
|
+
unless ActiveRecord::Base.connection.index_exists?(:temp_latest_tb_status, :obs_datetime)
|
1032
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX tlts_date ON temp_latest_tb_status(obs_datetime)'
|
1033
|
+
end
|
1034
|
+
unless ActiveRecord::Base.connection.index_exists?(:temp_latest_tb_status, :site_id)
|
1035
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX tlts_site ON temp_latest_tb_status(site_id)'
|
1036
|
+
end
|
1037
|
+
ActiveRecord::Base.connection.execute 'TRUNCATE temp_latest_tb_status'
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
def create_temp_latest_tb_status(end_date)
|
1041
|
+
ActiveRecord::Base.connection.select_all <<~SQL
|
1042
|
+
INSERT INTO temp_latest_tb_status
|
1043
|
+
SELECT t.person_id, MAX(t.obs_datetime) obs_datetime, t.site_id
|
1044
|
+
FROM obs t
|
1045
|
+
INNER JOIN temp_patient_outcomes o ON o.patient_id = t.person_id AND o.cum_outcome = 'On antiretrovirals' #{site_manager(operator: 'AND', column: 'o.site_id', location: @location)} #{site_manager(operator: 'AND', column: 't.site_id', location: @location)}
|
1046
|
+
WHERE t.concept_id = 7459 AND t.voided = 0 AND t.obs_datetime <= '#{end_date} 23:59:59' #{site_manager(operator: 'AND', column: 't.site_id', location: @location)}
|
1047
|
+
GROUP BY t.person_id
|
1048
|
+
SQL
|
1049
|
+
end
|
1050
|
+
|
1026
1051
|
def total_patients_with_screened_bp(total_alive_and_on_art, _start_date, end_date)
|
1027
1052
|
return 0 if total_alive_and_on_art.blank? || total_alive_and_on_art.empty?
|
1028
1053
|
|
@@ -1030,23 +1055,13 @@ module MalawiHivProgramReports
|
|
1030
1055
|
.select(:concept_id)
|
1031
1056
|
|
1032
1057
|
results = ActiveRecord::Base.connection.select_all <<~SQL
|
1033
|
-
SELECT
|
1034
|
-
FROM obs
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
AND obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')} AND obs_datetime >= #{interval_manager(date: end_date, value: 12, interval: 'MONTH', operator: '-')}
|
1041
|
-
AND #{in_manager(column: 'person_id', values: total_alive_and_on_art)} #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1042
|
-
GROUP BY person_id
|
1043
|
-
) AS max_obs
|
1044
|
-
ON max_obs.person_id = o.person_id
|
1045
|
-
AND max_obs.obs_datetime = o.obs_datetime
|
1046
|
-
WHERE o.voided = 0 #{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
1047
|
-
AND o.concept_id IN (#{bp_concepts.to_sql})
|
1048
|
-
AND (o.value_text IS NOT NULL OR o.value_numeric IS NOT NULL)
|
1049
|
-
GROUP BY o.person_id
|
1058
|
+
SELECT person_id
|
1059
|
+
FROM obs
|
1060
|
+
WHERE voided = 0 AND concept_id IN (#{bp_concepts.to_sql})
|
1061
|
+
AND (value_text IS NOT NULL OR value_numeric IS NOT NULL)
|
1062
|
+
AND obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')} AND obs_datetime >= #{interval_manager(date: end_date, value: 12, interval: 'MONTH', operator: '-')}
|
1063
|
+
AND #{in_manager(column: 'person_id', values: total_alive_and_on_art)} #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1064
|
+
GROUP BY person_id
|
1050
1065
|
SQL
|
1051
1066
|
|
1052
1067
|
((results.count.to_f / total_alive_and_on_art.count) * 100).to_i
|
@@ -1139,8 +1154,8 @@ module MalawiHivProgramReports
|
|
1139
1154
|
|
1140
1155
|
return [] if patient_ids.blank?
|
1141
1156
|
|
1142
|
-
results = ActiveRecord::Base.connection.select_all
|
1143
|
-
|
1157
|
+
results = ActiveRecord::Base.connection.select_all <<~SQL
|
1158
|
+
SELECT ods.patient_id
|
1144
1159
|
FROM orders ods
|
1145
1160
|
INNER JOIN drug_order dos ON ods.order_id = dos.order_id AND ods.voided = 0 #{site_manager(operator: 'AND',
|
1146
1161
|
column: 'dos.site_id', location: @location)}
|
@@ -1149,21 +1164,8 @@ module MalawiHivProgramReports
|
|
1149
1164
|
AND #{in_manager(column: 'ods.patient_id', values: patient_ids)}
|
1150
1165
|
AND ods.start_date BETWEEN '#{start_date.to_date.strftime('%Y-%m-%d 00:00:00')}'
|
1151
1166
|
AND '#{end_date.to_date.strftime('%Y-%m-%d 23:59:59')}'
|
1152
|
-
|
1153
|
-
|
1154
|
-
operator: 'AND', column: 'd.site_id', location: @location
|
1155
|
-
)}
|
1156
|
-
WHERE #{in_manager(column: 'o.concept_id',
|
1157
|
-
values: [
|
1158
|
-
isoniazid_concept_id, pyridoxine_concept_id
|
1159
|
-
])}
|
1160
|
-
AND o.patient_id = ods.patient_id #{site_manager(operator: 'AND',
|
1161
|
-
column: 'o.site_id', location: @location)}
|
1162
|
-
AND d.quantity IS NOT NULL
|
1163
|
-
AND o.start_date BETWEEN '#{start_date.to_date.strftime('%Y-%m-%d 00:00:00')}'
|
1164
|
-
AND '#{end_date.to_date.strftime('%Y-%m-%d 23:59:59')}')
|
1165
|
-
GROUP BY ods.patient_id"
|
1166
|
-
)
|
1167
|
+
GROUP BY ods.patient_id
|
1168
|
+
SQL
|
1167
1169
|
|
1168
1170
|
((results.count.to_f / patient_ids.count) * 100).to_i
|
1169
1171
|
end
|
@@ -1178,8 +1180,8 @@ module MalawiHivProgramReports
|
|
1178
1180
|
|
1179
1181
|
return [] if patient_ids.blank?
|
1180
1182
|
|
1181
|
-
results = ActiveRecord::Base.connection.select_all
|
1182
|
-
|
1183
|
+
results = ActiveRecord::Base.connection.select_all <<~SQL
|
1184
|
+
SELECT ods.patient_id
|
1183
1185
|
FROM orders ods
|
1184
1186
|
INNER JOIN drug_order dos ON ods.order_id = dos.order_id AND ods.voided = 0 #{site_manager(operator: 'AND',
|
1185
1187
|
column: 'dos.site_id', location: @location)}
|
@@ -1188,24 +1190,13 @@ module MalawiHivProgramReports
|
|
1188
1190
|
AND ods.patient_id in (#{patient_ids.join(',')})
|
1189
1191
|
AND ods.start_date BETWEEN '#{start_date.to_date.strftime('%Y-%m-%d 00:00:00')}'
|
1190
1192
|
AND '#{end_date.to_date.strftime('%Y-%m-%d 23:59:59')}'
|
1191
|
-
|
1192
|
-
|
1193
|
-
operator: 'AND', column: 'd.site_id', location: @location
|
1194
|
-
)}
|
1195
|
-
WHERE o.concept_id = #{cpt_concept_id} #{site_manager(operator: 'AND',
|
1196
|
-
column: 'o.site_id', location: @location)}
|
1197
|
-
AND d.quantity > 0
|
1198
|
-
AND o.patient_id = ods.patient_id
|
1199
|
-
AND o.start_date BETWEEN '#{start_date.to_date.strftime('%Y-%m-%d 00:00:00')}'
|
1200
|
-
AND '#{end_date.to_date.strftime('%Y-%m-%d 23:59:59')}')
|
1201
|
-
|
1202
|
-
GROUP BY ods.patient_id"
|
1203
|
-
)
|
1193
|
+
GROUP BY ods.patient_id
|
1194
|
+
SQL
|
1204
1195
|
|
1205
1196
|
((results.count.to_f / patient_ids.count) * 100).to_i
|
1206
1197
|
end
|
1207
1198
|
|
1208
|
-
def total_breastfeeding_women(_patients_list, total_pregnant_women, _start_date,
|
1199
|
+
def total_breastfeeding_women(_patients_list, total_pregnant_women, _start_date, _end_date)
|
1209
1200
|
total_pregnant_women = if total_pregnant_women.empty?
|
1210
1201
|
[0]
|
1211
1202
|
else
|
@@ -1228,39 +1219,24 @@ module MalawiHivProgramReports
|
|
1228
1219
|
ON enc.encounter_id = obs.encounter_id
|
1229
1220
|
AND enc.voided = 0 #{site_manager(operator: 'AND', column: 'enc.site_id', location: @location)}
|
1230
1221
|
AND enc.encounter_type IN (#{encounter_types.to_sql})
|
1222
|
+
AND obs.voided = 0 AND obs.concept_id IN (#{breastfeeding_concepts.to_sql}) #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1231
1223
|
INNER JOIN temp_earliest_start_date e
|
1232
1224
|
ON e.patient_id = enc.patient_id #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
|
1233
1225
|
AND LEFT(e.gender, 1) = 'F'
|
1226
|
+
AND e.patient_id NOT IN (#{total_pregnant_women.join(',')})
|
1234
1227
|
INNER JOIN temp_patient_outcomes
|
1235
1228
|
ON temp_patient_outcomes.patient_id = e.patient_id #{site_manager(operator: 'AND', column: 'temp_patient_outcomes.site_id', location: @location)}
|
1236
1229
|
AND temp_patient_outcomes.cum_outcome = 'On antiretrovirals'
|
1237
|
-
INNER JOIN
|
1238
|
-
|
1239
|
-
|
1240
|
-
INNER JOIN encounter
|
1241
|
-
ON encounter.encounter_id = obs.encounter_id
|
1242
|
-
AND encounter.encounter_type IN (#{encounter_types.to_sql})
|
1243
|
-
AND encounter.voided = 0 #{site_manager(operator: 'AND', column: 'encounter.site_id', location: @location)}
|
1244
|
-
WHERE person_id IN (SELECT patient_id FROM temp_patient_outcomes WHERE cum_outcome = 'On antiretrovirals')
|
1245
|
-
AND concept_id IN (#{breastfeeding_concepts.to_sql})
|
1246
|
-
AND obs.voided = 0 #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1247
|
-
AND obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
1248
|
-
GROUP BY person_id
|
1249
|
-
) AS max_obs
|
1250
|
-
ON max_obs.person_id = obs.person_id
|
1251
|
-
AND max_obs.obs_datetime = obs.obs_datetime
|
1252
|
-
WHERE obs.person_id = e.patient_id
|
1253
|
-
AND #{in_manager(column: 'obs.person_id', values: total_pregnant_women.join(','), negation: true)}
|
1254
|
-
AND obs.obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
1255
|
-
AND obs.concept_id IN (#{breastfeeding_concepts.to_sql})
|
1256
|
-
AND obs.voided = 0 #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1230
|
+
INNER JOIN tmp_max_drug_orders AS max_obs ON max_obs.patient_id = obs.person_id
|
1231
|
+
AND DATE(max_obs.start_date) = DATE(obs.obs_datetime) #{site_manager(operator: 'AND', column: 'max_obs.site_id', location: @location)}
|
1232
|
+
WHERE obs.person_id = e.patient_id #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1257
1233
|
GROUP BY obs.person_id #{@adapter == 'mysql2' ? '' : ', obs.value_coded'}
|
1258
1234
|
HAVING value_coded = 1065
|
1259
1235
|
ORDER BY MAX(obs.obs_datetime) DESC;
|
1260
1236
|
SQL
|
1261
1237
|
end
|
1262
1238
|
|
1263
|
-
def total_pregnant_women(_patients_list, _start_date,
|
1239
|
+
def total_pregnant_women(_patients_list, _start_date, _end_date)
|
1264
1240
|
encounter_types = ::EncounterType.where('LOWER(name) IN (?)',
|
1265
1241
|
['HIV CLINIC CONSULTATION'.downcase, 'HIV STAGING'.downcase])
|
1266
1242
|
.select(:encounter_type_id)
|
@@ -1272,32 +1248,19 @@ module MalawiHivProgramReports
|
|
1272
1248
|
ActiveRecord::Base.connection.select_all <<~SQL
|
1273
1249
|
SELECT obs.person_id, obs.value_coded
|
1274
1250
|
FROM obs obs
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1251
|
+
INNER JOIN encounter enc
|
1252
|
+
ON enc.encounter_id = obs.encounter_id
|
1253
|
+
AND enc.voided = 0 #{site_manager(operator: 'AND', column: 'enc.site_id', location: @location)}
|
1254
|
+
AND enc.encounter_type IN (#{encounter_types.to_sql})
|
1255
|
+
AND obs.voided = 0 AND obs.concept_id IN (#{pregnant_concepts.to_sql}) #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1256
|
+
INNER JOIN temp_earliest_start_date e
|
1257
|
+
ON e.patient_id = enc.patient_id #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
|
1258
|
+
AND LEFT(e.gender, 1) = 'F'
|
1282
1259
|
INNER JOIN temp_patient_outcomes
|
1283
1260
|
ON temp_patient_outcomes.patient_id = e.patient_id #{site_manager(operator: 'AND', column: 'temp_patient_outcomes.site_id', location: @location)}
|
1284
1261
|
AND temp_patient_outcomes.cum_outcome = 'On antiretrovirals'
|
1285
|
-
INNER JOIN
|
1286
|
-
|
1287
|
-
FROM obs
|
1288
|
-
INNER JOIN encounter
|
1289
|
-
ON encounter.encounter_id = obs.encounter_id #{site_manager(operator: 'AND', column: 'encounter.site_id', location: @location)}
|
1290
|
-
AND encounter.encounter_type IN (#{encounter_types.to_sql})
|
1291
|
-
AND encounter.voided = 0
|
1292
|
-
WHERE concept_id IN (#{pregnant_concepts.to_sql})
|
1293
|
-
AND obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
1294
|
-
AND obs.voided = 0 #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1295
|
-
GROUP BY person_id
|
1296
|
-
) AS max_obs
|
1297
|
-
ON max_obs.person_id = obs.person_id
|
1298
|
-
AND max_obs.obs_datetime = obs.obs_datetime
|
1299
|
-
WHERE obs.concept_id IN (#{pregnant_concepts.to_sql})
|
1300
|
-
AND obs.voided = 0 #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1262
|
+
INNER JOIN tmp_max_drug_orders AS max_obs ON max_obs.patient_id = obs.person_id
|
1263
|
+
AND DATE(max_obs.start_date) = DATE(obs.obs_datetime) #{site_manager(operator: 'AND', column: 'max_obs.site_id', location: @location)}
|
1301
1264
|
GROUP BY obs.person_id #{@adapter == 'mysql2' ? '' : ', obs.value_coded'}
|
1302
1265
|
HAVING obs.value_coded = 1065
|
1303
1266
|
ORDER BY MAX(obs.obs_datetime) DESC;
|
@@ -1338,28 +1301,13 @@ module MalawiHivProgramReports
|
|
1338
1301
|
def latest_art_adherence(patients_alive_and_on_art, _start_date, end_date)
|
1339
1302
|
patients_alive_and_on_art = Set.new(patients_alive_and_on_art.map { |patient| patient['patient_id'] })
|
1340
1303
|
end_date = ActiveRecord::Base.connection.quote(end_date)
|
1304
|
+
create_tmp_max_adherence(end_date)
|
1341
1305
|
|
1342
1306
|
not_adherent = ActiveRecord::Base.connection.select_all <<~SQL
|
1343
1307
|
SELECT adherence.person_id
|
1344
1308
|
FROM obs AS adherence
|
1345
|
-
INNER JOIN
|
1346
|
-
|
1347
|
-
FROM obs
|
1348
|
-
INNER JOIN orders
|
1349
|
-
ON orders.order_id = obs.order_id #{site_manager(operator: 'AND', column: 'orders.site_id', location: @location)}
|
1350
|
-
AND orders.concept_id IN (#{arv_drug_concepts.to_sql})
|
1351
|
-
AND orders.order_type_id = #{drug_order_type.order_type_id}
|
1352
|
-
AND orders.voided = 0
|
1353
|
-
INNER JOIN temp_patient_outcomes
|
1354
|
-
ON temp_patient_outcomes.patient_id = obs.person_id #{site_manager(operator: 'AND', column: 'temp_patient_outcomes.site_id', location: @location)}
|
1355
|
-
AND LOWER(temp_patient_outcomes.cum_outcome) = LOWER('On antiretrovirals')
|
1356
|
-
WHERE obs.concept_id = #{drug_order_adherence_concept.concept_id}
|
1357
|
-
AND obs.obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
1358
|
-
AND (obs.value_numeric IS NOT NULL OR obs.value_text IS NOT NULL)
|
1359
|
-
AND obs.voided = 0 #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1360
|
-
GROUP BY obs.person_id
|
1361
|
-
) AS max_adherence
|
1362
|
-
ON max_adherence.person_id = adherence.person_id
|
1309
|
+
INNER JOIN tmp_max_adherence AS max_adherence
|
1310
|
+
ON max_adherence.person_id = adherence.person_id #{site_manager(operator: 'AND', column: 'max_adherence.site_id', location: @location)}
|
1363
1311
|
AND adherence.obs_datetime >= max_adherence.visit_date #{site_manager(operator: 'AND', column: 'adherence.site_id', location: @location)}
|
1364
1312
|
AND adherence.obs_datetime < #{interval_manager(date: 'max_adherence.visit_date', value: 1, interval: 'DAY', operator: '+')}
|
1365
1313
|
INNER JOIN orders
|
@@ -1383,27 +1331,11 @@ module MalawiHivProgramReports
|
|
1383
1331
|
adherent = ActiveRecord::Base.connection.select_all <<~SQL
|
1384
1332
|
SELECT adherence.person_id
|
1385
1333
|
FROM obs AS adherence
|
1386
|
-
INNER JOIN
|
1387
|
-
|
1388
|
-
FROM obs
|
1389
|
-
INNER JOIN orders
|
1390
|
-
ON orders.order_id = obs.order_id
|
1391
|
-
AND orders.concept_id IN (#{arv_drug_concepts.to_sql})
|
1392
|
-
AND orders.order_type_id = #{drug_order_type.order_type_id}
|
1393
|
-
AND orders.voided = 0 #{site_manager(operator: 'AND', column: 'orders.site_id', location: @location)}
|
1394
|
-
INNER JOIN temp_patient_outcomes
|
1395
|
-
ON temp_patient_outcomes.patient_id = obs.person_id #{site_manager(operator: 'AND', column: 'temp_patient_outcomes.site_id', location: @location)}
|
1396
|
-
AND #{in_manager(column: 'temp_patient_outcomes.patient_id', values: not_adherent.blank? ? [0] : not_adherent.join(','), negation: true)}
|
1397
|
-
AND LOWER(temp_patient_outcomes.cum_outcome) = LOWER('On antiretrovirals')
|
1398
|
-
WHERE obs.concept_id = #{drug_order_adherence_concept.concept_id}
|
1399
|
-
AND obs.obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
1400
|
-
AND (obs.value_numeric IS NOT NULL OR obs.value_text IS NOT NULL)
|
1401
|
-
AND obs.voided = 0 #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1402
|
-
GROUP BY obs.person_id
|
1403
|
-
) AS max_adherence
|
1404
|
-
ON max_adherence.person_id = adherence.person_id
|
1334
|
+
INNER JOIN tmp_max_adherence AS max_adherence
|
1335
|
+
ON max_adherence.person_id = adherence.person_id #{site_manager(operator: 'AND', column: 'max_adherence.site_id', location: @location)}
|
1405
1336
|
AND adherence.obs_datetime >= max_adherence.visit_date #{site_manager(operator: 'AND', column: 'adherence.site_id', location: @location)}
|
1406
1337
|
AND adherence.obs_datetime < #{interval_manager(date: 'max_adherence.visit_date', value: 1, interval: 'DAY', operator: '+')}
|
1338
|
+
AND max_adherence.person_id NOT IN (#{not_adherent.blank? ? 0 : not_adherent.join(',')})
|
1407
1339
|
INNER JOIN orders
|
1408
1340
|
ON orders.order_id = adherence.order_id
|
1409
1341
|
AND orders.order_type_id = #{drug_order_type.order_type_id}
|
@@ -1424,6 +1356,43 @@ module MalawiHivProgramReports
|
|
1424
1356
|
[adherent.uniq, not_adherent.uniq, unknown_adherence]
|
1425
1357
|
end
|
1426
1358
|
|
1359
|
+
def create_tmp_max_adherence(end_date)
|
1360
|
+
drop_tmp_max_adherence
|
1361
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
1362
|
+
CREATE TABLE tmp_max_adherence (
|
1363
|
+
person_id INT PRIMARY KEY,
|
1364
|
+
visit_date DATE,
|
1365
|
+
site_id INT NOT NULL
|
1366
|
+
)
|
1367
|
+
SQL
|
1368
|
+
|
1369
|
+
ActiveRecord::Base.connection.execute('CREATE INDEX tma_date ON tmp_max_adherence (visit_date)')
|
1370
|
+
ActiveRecord::Base.connection.execute('CREATE INDEX tma_site ON tmp_max_adherence (site_id)')
|
1371
|
+
|
1372
|
+
ActiveRecord::Base.connection.execute <<~SQL
|
1373
|
+
INSERT INTO tmp_max_adherence
|
1374
|
+
SELECT obs.person_id, DATE(MAX(obs.obs_datetime)) AS visit_date, obs.site_id
|
1375
|
+
FROM obs
|
1376
|
+
INNER JOIN orders
|
1377
|
+
ON orders.order_id = obs.order_id
|
1378
|
+
AND orders.concept_id IN (SELECT `concept_set`.`concept_id` FROM `concept_set` WHERE `concept_set`.`concept_set` = 1085)
|
1379
|
+
AND orders.order_type_id = 1
|
1380
|
+
AND orders.voided = 0 #{site_manager(operator: 'AND', column: 'orders.site_id', location: @location)}
|
1381
|
+
INNER JOIN temp_patient_outcomes
|
1382
|
+
ON temp_patient_outcomes.patient_id = obs.person_id
|
1383
|
+
AND temp_patient_outcomes.cum_outcome = 'On antiretrovirals' #{site_manager(operator: 'AND', column: 'temp_patient_outcomes.site_id', location: @location)}
|
1384
|
+
WHERE obs.concept_id = 6987
|
1385
|
+
AND obs.obs_datetime < (DATE(#{end_date}) + INTERVAL 1 DAY)
|
1386
|
+
AND (obs.value_numeric IS NOT NULL OR obs.value_text IS NOT NULL)
|
1387
|
+
AND obs.voided = 0 #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1388
|
+
GROUP BY obs.person_id;
|
1389
|
+
SQL
|
1390
|
+
end
|
1391
|
+
|
1392
|
+
def drop_tmp_max_adherence
|
1393
|
+
ActiveRecord::Base.connection.execute('DROP TABLE IF EXISTS tmp_max_adherence')
|
1394
|
+
end
|
1395
|
+
|
1427
1396
|
def adherence_encounter
|
1428
1397
|
@adherence_encounter ||= encounter_type('ART ADHERENCE')
|
1429
1398
|
end
|
@@ -1514,9 +1483,8 @@ module MalawiHivProgramReports
|
|
1514
1483
|
SELECT e.*, s.has_se
|
1515
1484
|
FROM temp_earliest_start_date e
|
1516
1485
|
INNER JOIN temp_patient_side_effects s ON s.patient_id = e.patient_id #{site_manager(operator: 'AND', column: 's.site_id', location: @location)}
|
1517
|
-
INNER JOIN temp_patient_outcomes o ON o.patient_id = e.patient_id #{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
1518
|
-
WHERE
|
1519
|
-
AND DATE(e.date_enrolled) <= '#{end_date.to_date}';
|
1486
|
+
INNER JOIN temp_patient_outcomes o ON o.patient_id = e.patient_id AND LOWER(o.cum_outcome) = LOWER('On antiretrovirals') #{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
1487
|
+
WHERE DATE(e.date_enrolled) <= '#{end_date.to_date}' #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)};
|
1520
1488
|
SQL
|
1521
1489
|
|
1522
1490
|
(records || []).each do |data|
|
@@ -1631,10 +1599,10 @@ module MalawiHivProgramReports
|
|
1631
1599
|
ActiveRecord::Base.connection.select_all <<~SQL
|
1632
1600
|
SELECT t.patient_id
|
1633
1601
|
FROM temp_earliest_start_date t
|
1634
|
-
INNER JOIN obs ON t.patient_id = obs.person_id
|
1635
|
-
|
1636
|
-
AND
|
1637
|
-
|
1602
|
+
INNER JOIN obs ON t.patient_id = obs.person_id
|
1603
|
+
AND ((value_coded = #{concept_id} AND concept_id = #{who_stages_criteria}) OR (concept_id = #{concept_id}) AND value_coded = #{yes_concept_id} )
|
1604
|
+
AND voided = 0 AND DATE(obs_datetime) <= DATE(date_enrolled) #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1605
|
+
WHERE t.date_enrolled BETWEEN '#{start_date}' AND '#{end_date}' #{site_manager(operator: 'AND', column: 't.site_id', location: @location)}
|
1638
1606
|
GROUP BY patient_id
|
1639
1607
|
SQL
|
1640
1608
|
end
|
@@ -1650,12 +1618,12 @@ module MalawiHivProgramReports
|
|
1650
1618
|
ActiveRecord::Base.connection.select_all <<~SQL
|
1651
1619
|
SELECT t.patient_id
|
1652
1620
|
FROM temp_earliest_start_date t
|
1653
|
-
INNER JOIN obs ON t.patient_id = obs.person_id
|
1654
|
-
|
1655
|
-
|
1656
|
-
OR
|
1621
|
+
INNER JOIN obs ON t.patient_id = obs.person_id AND voided = 0
|
1622
|
+
AND DATE(obs_datetime) <= DATE(date_enrolled) #{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
1623
|
+
AND ( (#{in_manager(column: 'value_coded', values: [eptb_concept_id, pulmonary_tb_concept_id, current_ptb_concept_id])} AND concept_id = #{who_stages_criteria} )
|
1624
|
+
OR
|
1657
1625
|
(#{in_manager(column: 'concept_id', values: [eptb_concept_id, pulmonary_tb_concept_id, current_ptb_concept_id])} AND value_coded = #{yes_concept_id}))
|
1658
|
-
|
1626
|
+
WHERE date_enrolled BETWEEN '#{start_date}' AND '#{end_date}' #{site_manager(operator: 'AND', column: 't.site_id', location: @location)}
|
1659
1627
|
GROUP BY patient_id
|
1660
1628
|
SQL
|
1661
1629
|
end
|
@@ -1949,30 +1917,25 @@ module MalawiHivProgramReports
|
|
1949
1917
|
ActiveRecord::Base.connection.execute 'DROP TABLE IF EXISTS temp_pregnant_obs;'
|
1950
1918
|
ActiveRecord::Base.connection.execute <<~SQL
|
1951
1919
|
CREATE TABLE temp_pregnant_obs
|
1952
|
-
SELECT o.person_id,o.value_coded, o.obs_datetime, o.site_id
|
1920
|
+
SELECT o.person_id,o.value_coded, DATE(o.obs_datetime) obs_datetime, o.site_id
|
1953
1921
|
FROM obs o
|
1954
1922
|
WHERE o.concept_id IN (6131,1755,7972,7563)
|
1955
|
-
AND o.value_coded IN (1065,1755)
|
1923
|
+
AND o.value_coded IN (1065,1755)
|
1956
1924
|
AND o.voided = 0 #{site_manager(operator: 'AND', column: 'o.location_id', location: @location)}
|
1957
1925
|
AND o.obs_datetime >= '#{start_date}' AND o.obs_datetime < '#{end_date}' + INTERVAL 1 DAY;
|
1958
1926
|
SQL
|
1959
1927
|
ActiveRecord::Base.connection.execute 'CREATE INDEX fre_person ON temp_pregnant_obs(person_id);'
|
1960
1928
|
ActiveRecord::Base.connection.execute 'CREATE INDEX fre_obs_time ON temp_pregnant_obs(obs_datetime);'
|
1929
|
+
ActiveRecord::Base.connection.execute 'CREATE INDEX fre_site ON temp_pregnant_obs(site_id);'
|
1961
1930
|
end
|
1962
1931
|
|
1963
1932
|
def pregnant_females_all_ages(start_date, end_date)
|
1964
|
-
concept('Yes').concept_id
|
1965
|
-
concept('IS PATIENT PREGNANT?').concept_id
|
1966
|
-
concept('PATIENT PREGNANT').concept_id
|
1967
|
-
concept('PREGNANT AT INITIATION?').concept_id
|
1968
|
-
concept('Reason for ART eligibility').concept_id
|
1969
|
-
|
1970
1933
|
# (patient_id_plus_date_enrolled || []).each do |patient_id, date_enrolled|
|
1971
1934
|
registered = ActiveRecord::Base.connection.select_all <<~SQL
|
1972
1935
|
SELECT tesd.*, ft.value_coded
|
1973
1936
|
FROM temp_earliest_start_date tesd#{' '}
|
1974
|
-
INNER JOIN temp_pregnant_obs ft ON ft.person_id = tesd.patient_id AND
|
1975
|
-
AND tesd.gender = 'F'
|
1937
|
+
INNER JOIN temp_pregnant_obs ft ON ft.person_id = tesd.patient_id AND ft.obs_datetime = tesd.earliest_start_date
|
1938
|
+
AND tesd.gender = 'F' #{site_manager(operator: 'AND', column: 'ft.site_id', location: @location)}
|
1976
1939
|
WHERE tesd.gender = 'F' and tesd.date_enrolled >= DATE('#{start_date}') AND tesd.date_enrolled <= DATE('#{end_date}') #{site_manager(operator: 'AND', column: 'tesd.site_id', location: @location)}
|
1977
1940
|
GROUP BY tesd.patient_id
|
1978
1941
|
SQL
|
@@ -1983,8 +1946,8 @@ module MalawiHivProgramReports
|
|
1983
1946
|
WHERE date_enrolled BETWEEN '#{start_date}' AND '#{end_date}'
|
1984
1947
|
AND gender IN ('F','Female') #{site_manager(operator: 'AND', column: 'site_id', location: @location)}
|
1985
1948
|
AND reason_for_starting_art IN (6131,1755,7972,7563)
|
1986
|
-
GROUP BY patient_id
|
1987
1949
|
SQL
|
1950
|
+
|
1988
1951
|
pregnant_at_initiation_ids = []
|
1989
1952
|
(pregnant_at_initiation || []).each do |patient|
|
1990
1953
|
pregnant_at_initiation_ids << patient['patient_id'].to_i
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: malawi_hiv_program_reports
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roy Chanunkha
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|