malawi_hiv_program_reports 1.1.1 → 1.1.3
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 -1
- data/app/services/malawi_hiv_program_reports/cohort/disaggregated.rb +204 -0
- data/app/services/malawi_hiv_program_reports/moh/cumulative_cohort.rb +1 -1
- data/app/services/malawi_hiv_program_reports/pepfar/utils.rb +28 -22
- data/app/services/malawi_hiv_program_reports/pepfar/viral_load_coverage2.rb +24 -53
- data/app/services/malawi_hiv_program_reports/report_map.rb +1 -1
- data/lib/malawi_hiv_program_reports/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed231eff9bb9c45a7d57027366c82fc112fc1de0cb6c4f457cd87bfeed1bd908
|
4
|
+
data.tar.gz: 3b9a9292285146cac5a4f202bf2d2266fdf323f1acdb67a94706efee322f4afe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2dab0b971e5a76b0097586837b7adb5869d5c0d34563824cc79d02b8cce0679f22a1afce0955b3a733663e017a6886ccced14f924dd5636f34026c05fc6649b4
|
7
|
+
data.tar.gz: 7015b44578a5bdfaea8a15c2b85b03823688b5a13fdf37e683612549c257376c0583117a28b03332d4af53c2561069c1b5d406862fd341ba15e0c724b0bbdfe7
|
@@ -0,0 +1,204 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MalawiHivProgramReports
|
4
|
+
module Cohort
|
5
|
+
# Disaggregated cohort report
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
7
|
+
class Disaggregated
|
8
|
+
attr_accessor :type, :start_date, :end_date, :rebuild, :occupation, :report, :maternal, :location
|
9
|
+
|
10
|
+
include MalawiHivProgramReports::Utils::ModelUtils
|
11
|
+
include MalawiHivProgramReports::Pepfar::Utils
|
12
|
+
include MalawiHivProgramReports::Adapters::Moh::Custom
|
13
|
+
|
14
|
+
def initialize(start_date:, end_date:, **kwargs)
|
15
|
+
@type = kwargs[:definition] || 'pepfar'
|
16
|
+
@start_date = start_date
|
17
|
+
@end_date = end_date
|
18
|
+
@rebuild = kwargs[:rebuild]&.casecmp?('true')
|
19
|
+
@occupation = kwargs[:occupation]
|
20
|
+
@location = kwargs[:location]
|
21
|
+
@maternal = {}
|
22
|
+
|
23
|
+
# raise an error if location is empty
|
24
|
+
raise 'Location cannot be empty' if @location.blank?
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_report
|
28
|
+
rebuild_report if rebuild
|
29
|
+
process_initialization
|
30
|
+
process_data
|
31
|
+
flatten_and_sort_data
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
GENDER = %w[M F].freeze
|
37
|
+
AGGREGATE_GENDER_ROWS = %w[M FP FNP FBf].freeze
|
38
|
+
|
39
|
+
def process_initialization
|
40
|
+
init_report
|
41
|
+
init_aggregate_rows
|
42
|
+
end
|
43
|
+
|
44
|
+
def init_report
|
45
|
+
@report = pepfar_age_groups.each_with_object({}) do |age_group, report|
|
46
|
+
report[age_group] = {}
|
47
|
+
GENDER.each do |gender|
|
48
|
+
report[age_group][gender] = {}
|
49
|
+
init_cohort_section(report[age_group][gender])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def init_aggregate_rows
|
55
|
+
report['All'] = {}
|
56
|
+
AGGREGATE_GENDER_ROWS.each do |gender|
|
57
|
+
report['All'][gender] = {}
|
58
|
+
init_cohort_section(report['All'][gender])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def init_cohort_section(cursor)
|
63
|
+
cursor['tx_curr'] = []
|
64
|
+
(COHORT_REGIMENS + ['Unknown']).each do |regimen|
|
65
|
+
cursor[regimen] = []
|
66
|
+
end
|
67
|
+
cursor['unknown'] = []
|
68
|
+
cursor['total'] = []
|
69
|
+
end
|
70
|
+
|
71
|
+
def process_data
|
72
|
+
process_db_data
|
73
|
+
process_maternal_data
|
74
|
+
end
|
75
|
+
|
76
|
+
# rubocop:disable Metrics/AbcSize
|
77
|
+
def process_db_data
|
78
|
+
fetch_data.each do |data|
|
79
|
+
age_group = data['age_group']
|
80
|
+
regimen = data['regimen'] || 'Unknown'
|
81
|
+
patient_id = data['patient_id']
|
82
|
+
# we need to handle regimes that only have one P to become PP. Otherwise if it is already PP or PA we leave
|
83
|
+
# it as is. Regimens are in this format NUMBERLETTERS
|
84
|
+
regimen = regimen.gsub(/(\d+[A-Za-z]*P)\z/, '\1P') if regimen.match?(/\A\d+[A-Za-z]*[^P]P\z/)
|
85
|
+
gender = data['gender']
|
86
|
+
report[age_group.to_s][gender.to_s][regimen.to_s] << patient_id
|
87
|
+
report[age_group.to_s][gender.to_s]['tx_curr'] << patient_id
|
88
|
+
report[age_group.to_s][gender.to_s]['total'] << patient_id
|
89
|
+
process_aggregate_rows(gender:, regimen:, patient_id:)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def process_maternal_data
|
94
|
+
result = MalawiHivProgramReports::Pepfar::ViralLoadCoverage2.new(start_date:, end_date:, location:)
|
95
|
+
.vl_maternal_status(maternal.keys)
|
96
|
+
# result comes in this form: { FP: [], FBf: [] }
|
97
|
+
# we need to loop through the keys
|
98
|
+
result.each_key do |key|
|
99
|
+
result[key].each do |patient_id|
|
100
|
+
report['All'][key.to_s]['tx_curr'] << patient_id
|
101
|
+
report['All'][key.to_s][maternal[patient_id].to_s] << patient_id
|
102
|
+
report['All'][key.to_s]['total'] << patient_id
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
# rubocop:enable Metrics/AbcSize
|
107
|
+
|
108
|
+
def process_aggregate_rows(gender:, regimen:, patient_id:)
|
109
|
+
if gender == 'M'
|
110
|
+
report['All']['M']['tx_curr'] << patient_id
|
111
|
+
report['All']['M'][regimen.to_s] << patient_id
|
112
|
+
report['All']['M']['total'] << patient_id
|
113
|
+
else
|
114
|
+
maternal[patient_id] = regimen
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# we need to flatten the data
|
119
|
+
def flatten_data
|
120
|
+
flat_data = []
|
121
|
+
report.each do |age_group, gender_data|
|
122
|
+
gender_data.each do |gender, regimen_data|
|
123
|
+
flat_data << {
|
124
|
+
'age_group' => age_group,
|
125
|
+
'gender' => gender,
|
126
|
+
**regimen_data
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
flat_data
|
131
|
+
end
|
132
|
+
|
133
|
+
def flatten_and_sort_data
|
134
|
+
flat_data = flatten_data
|
135
|
+
|
136
|
+
age_group_order = ['Unknown', '<1 year', '1-4 years', '5-9 years', '10-14 years', '15-19 years',
|
137
|
+
'20-24 years', '25-29 years', '30-34 years', '35-39 years', '40-44 years', '45-49 years',
|
138
|
+
'50-54 years', '55-59 years', '60-64 years', '65-69 years', '70-74 years', '75-79 years',
|
139
|
+
'80-84 years', '85-89 years', '90 plus years', 'All']
|
140
|
+
gender_order = %w[F M FP FNP FBF]
|
141
|
+
|
142
|
+
flat_data.sort_by do |row|
|
143
|
+
[age_group_order.index(row['age_group']) || Float::INFINITY,
|
144
|
+
gender_order.index(row['gender']) || Float::INFINITY]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# rubocop:disable Metrics/MethodLength
|
149
|
+
def fetch_data
|
150
|
+
ActiveRecord::Base.connection.select_all <<~SQL
|
151
|
+
SELECT
|
152
|
+
prescriptions.patient_id,
|
153
|
+
COALESCE(regimens.name, 'unknown') AS regimen,
|
154
|
+
prescriptions.age_group,
|
155
|
+
prescriptions.gender
|
156
|
+
FROM (
|
157
|
+
SELECT
|
158
|
+
tcm.patient_id,
|
159
|
+
GROUP_CONCAT(DISTINCT(tcm.drug_id) ORDER BY tcm.drug_id ASC) AS drugs,
|
160
|
+
disaggregated_age_group(date(earliest_start_date.birthdate), date('#{end_date}')) AS age_group,
|
161
|
+
earliest_start_date.gender
|
162
|
+
FROM cdr_temp_current_medication #{current_partition} tcm
|
163
|
+
INNER JOIN cdr_temp_patient_outcomes #{current_partition} AS outcomes ON outcomes.patient_id = tcm.patient_id AND outcomes.cum_outcome = 'On antiretrovirals'
|
164
|
+
INNER JOIN cdr_temp_cohort_members #{current_partition} AS earliest_start_date ON earliest_start_date.patient_id = tcm.patient_id
|
165
|
+
GROUP BY tcm.patient_id
|
166
|
+
) AS prescriptions
|
167
|
+
LEFT JOIN (
|
168
|
+
SELECT GROUP_CONCAT(drug.drug_id ORDER BY drug.drug_id ASC) AS drugs, regimen_name.name AS name
|
169
|
+
FROM moh_regimen_combination AS combo
|
170
|
+
INNER JOIN moh_regimen_combination_drug AS drug USING (regimen_combination_id)
|
171
|
+
INNER JOIN moh_regimen_name AS regimen_name USING (regimen_name_id)
|
172
|
+
GROUP BY combo.regimen_combination_id
|
173
|
+
) AS regimens ON regimens.drugs = prescriptions.drugs
|
174
|
+
SQL
|
175
|
+
end
|
176
|
+
# rubocop:enable Metrics/MethodLength
|
177
|
+
|
178
|
+
def update_outcomes
|
179
|
+
if check_if_table_exists('cdr_temp_patient_outcomes')
|
180
|
+
MalawiHivProgramReports::Moh::CumulativeOutcome.new(end_date:, start_date:, definition:,
|
181
|
+
rebuild: 'true', location:).find_report
|
182
|
+
else
|
183
|
+
rebuild_report
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def rebuild_report
|
188
|
+
MalawiHivProgramReports::Moh::CumulativeCohort.new(definition:, start_date:, end_date:,
|
189
|
+
locations: [location], rebuild: 'true').find_report
|
190
|
+
end
|
191
|
+
|
192
|
+
def check_if_table_exists(table_name)
|
193
|
+
result = ActiveRecord::Base.connection.select_one <<~SQL
|
194
|
+
SELECT COUNT(*) AS count
|
195
|
+
FROM information_schema.tables
|
196
|
+
WHERE table_schema = DATABASE()
|
197
|
+
AND table_name = '#{table_name}'
|
198
|
+
SQL
|
199
|
+
result['count'].to_i.positive?
|
200
|
+
end
|
201
|
+
end
|
202
|
+
# rubocop:enable Metrics/ClassLength
|
203
|
+
end
|
204
|
+
end
|
@@ -78,7 +78,7 @@ module MalawiHivProgramReports
|
|
78
78
|
# rubocop:enable Metrics/MethodLength
|
79
79
|
|
80
80
|
def reprocess_failed
|
81
|
-
failed_locs =
|
81
|
+
failed_locs = failed_sites&.map { |loc| loc[:site_id] }
|
82
82
|
return if failed_locs.empty?
|
83
83
|
|
84
84
|
process_thread(locations: failed_locs)
|
@@ -25,6 +25,11 @@ module MalawiHivProgramReports
|
|
25
25
|
].freeze
|
26
26
|
end
|
27
27
|
|
28
|
+
COHORT_REGIMENS = %w[
|
29
|
+
0P 2P 4PP 4PA 9PP 9PA 11PP 11PA 12PP 12PA 14PP 14PA 15PP 15PA 16P 17PP 17PA
|
30
|
+
4A 5A 6A 7A 8A 9A 10A 11A 12A 13A 14A 15A 16A 17A
|
31
|
+
].freeze
|
32
|
+
|
28
33
|
##
|
29
34
|
# Returns the drilldown information for all specified patients (ie patient_ids)
|
30
35
|
#
|
@@ -54,8 +59,8 @@ module MalawiHivProgramReports
|
|
54
59
|
# In some clinics like Lighthouse Filing numbers are used exclusively and in other
|
55
60
|
# sites, ARV Numbers are used.
|
56
61
|
def pepfar_patient_identifier_type
|
57
|
-
name = GlobalProperty.find_by(property: 'use.filing.numbers')&.property_value
|
58
|
-
name =
|
62
|
+
name = GlobalProperty.find_by(property: 'use.filing.numbers')&.property_value
|
63
|
+
name = name.present? && name == 'true' ? 'Filing number' : 'ARV Number'
|
59
64
|
::PatientIdentifierType.where(name:).select(:patient_identifier_type_id)
|
60
65
|
end
|
61
66
|
|
@@ -95,25 +100,25 @@ module MalawiHivProgramReports
|
|
95
100
|
hiv_clinic_registration_id = ::EncounterType.find_by_name('HIV CLINIC REGISTRATION').encounter_type_id
|
96
101
|
|
97
102
|
res = ActiveRecord::Base.connection.select_all <<~SQL
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
103
|
+
SELECT p.person_id patient_id
|
104
|
+
FROM person #{current_partition} p
|
105
|
+
INNER JOIN patient_program #{current_partition} pp ON pp.patient_id = p.person_id AND pp.program_id = #{::Program.find_by_name('HIV PROGRAM').id} AND pp.voided = 0
|
106
|
+
INNER JOIN patient_state #{current_partition} ps ON ps.patient_program_id = pp.patient_program_id AND ps.state = 7 AND ps.start_date IS NOT NULL
|
107
|
+
LEFT JOIN encounter #{current_partition} as hiv_registration ON hiv_registration.patient_id = p.person_id AND hiv_registration.encounter_datetime < DATE(#{ActiveRecord::Base.connection.quote(end_date)}) AND hiv_registration.encounter_type = #{hiv_clinic_registration_id} AND hiv_registration.voided = 0
|
108
|
+
LEFT JOIN (
|
109
|
+
SELECT * FROM obs #{current_partition} WHERE concept_id = #{type_of_patient_concept} AND voided = 0 AND value_coded = #{new_patient_concept} AND obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
110
|
+
) AS new_patient ON p.person_id = new_patient.person_id
|
111
|
+
LEFT JOIN (
|
112
|
+
SELECT * FROM obs #{current_partition} WHERE concept_id = #{type_of_patient_concept} AND voided = 0 AND value_coded = #{drug_refill_concept} AND obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
113
|
+
) AS refill ON p.person_id = refill.person_id
|
114
|
+
LEFT JOIN (
|
115
|
+
SELECT * FROM obs #{current_partition} WHERE concept_id = #{type_of_patient_concept} AND voided = 0 AND value_coded = #{external_concept} AND obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY', operator: '+')}
|
116
|
+
) AS external ON p.person_id = external.person_id
|
117
|
+
WHERE (refill.value_coded IS NOT NULL OR external.value_coded IS NOT NULL)
|
118
|
+
AND NOT (hiv_registration.encounter_id IS NOT NULL OR new_patient.value_coded IS NOT NULL)
|
119
|
+
GROUP BY p.person_id
|
120
|
+
ORDER BY hiv_registration.encounter_datetime DESC, refill.obs_datetime DESC, external.obs_datetime DESC
|
121
|
+
SQL
|
117
122
|
res.each do |record|
|
118
123
|
to_remove << record['patient_id'].to_i
|
119
124
|
end
|
@@ -138,7 +143,8 @@ module MalawiHivProgramReports
|
|
138
143
|
def patient_on_tb_treatment?(patient_id)
|
139
144
|
::Observation.where(person_id: patient_id, concept_id: ::ConceptName.find_by_name('TB status').concept_id,
|
140
145
|
value_coded: ::ConceptName.find_by_name('Confirmed TB on treatment').concept_id)
|
141
|
-
.where("obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY',
|
146
|
+
.where("obs_datetime < #{interval_manager(date: end_date, value: 1, interval: 'DAY',
|
147
|
+
operator: '+')}").exists?
|
142
148
|
end
|
143
149
|
end
|
144
150
|
end
|
@@ -9,18 +9,17 @@ module MalawiHivProgramReports
|
|
9
9
|
# 4. for the sample drawns available pick the latest sample drawn within the reporting period
|
10
10
|
# 5. for the results pick the latest result within the reporting period
|
11
11
|
class ViralLoadCoverage2
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
attr_reader :start_date, :end_date, :location
|
12
|
+
include Utils
|
13
|
+
include MalawiHivProgramReports::Utils::CommonSqlQueryUtils
|
14
|
+
include MalawiHivProgramReports::Adapters::Moh::Custom
|
15
|
+
include MalawiHivProgramReports::Utils::ModelUtils
|
16
|
+
attr_reader :start_date, :end_date, :location
|
18
17
|
|
19
18
|
def initialize(start_date:, end_date:, **kwargs)
|
20
19
|
@start_date = start_date&.to_date
|
21
20
|
raise InvalidParameterError, 'start_date is required' unless @start_date
|
22
21
|
|
23
|
-
@end_date = end_date&.to_date || @start_date + 12.months
|
22
|
+
@end_date = end_date&.to_date || (@start_date + 12.months)
|
24
23
|
raise InvalidParameterError, "start_date can't be greater than end_date" if @start_date > @end_date
|
25
24
|
|
26
25
|
@occupation = kwargs.delete(:occupation)
|
@@ -56,9 +55,9 @@ module MalawiHivProgramReports
|
|
56
55
|
start = Time.now
|
57
56
|
results = clients_on_art
|
58
57
|
# get all clients that are females from results
|
59
|
-
@maternal_status = vl_maternal_status(results.
|
58
|
+
@maternal_status = vl_maternal_status(results.filter_map do |patient|
|
60
59
|
patient['patient_id'] if patient['gender'] == 'F'
|
61
|
-
end
|
60
|
+
end)
|
62
61
|
if @type.blank? || @type == 'poc'
|
63
62
|
Parallel.each(results, in_threads: 20) do |patient|
|
64
63
|
process_client_eligibility(patient)
|
@@ -111,7 +110,7 @@ module MalawiHivProgramReports
|
|
111
110
|
length = 12
|
112
111
|
length = 6 if patient['maternal_status'] == 'FP'
|
113
112
|
length = 6 if patient['maternal_status'] == 'FBf'
|
114
|
-
length = 6 if patient['current_regimen'].to_s
|
113
|
+
length = 6 if /P/i.match?(patient['current_regimen'].to_s)
|
115
114
|
|
116
115
|
if patient['vl_order_date'] && patient['vl_order_date'].to_date >= end_date - 12.months && patient['vl_order_date'].to_date <= end_date
|
117
116
|
return false
|
@@ -125,27 +124,14 @@ module MalawiHivProgramReports
|
|
125
124
|
ActiveRecord::Base.connection.select_all <<~SQL
|
126
125
|
SELECT o.person_id, o.value_coded
|
127
126
|
FROM obs #{current_partition} o
|
128
|
-
|
129
|
-
#{
|
130
|
-
|
131
|
-
|
132
|
-
INNER JOIN (
|
133
|
-
SELECT person_id, MAX(obs_datetime) AS obs_datetime
|
134
|
-
FROM obs #{current_partition}
|
135
|
-
INNER JOIN encounter #{current_partition} ON encounter.encounter_id = obs.encounter_id AND encounter.encounter_type IN (#{encounter_types.to_sql}) AND encounter.voided = 0
|
136
|
-
#{site_manager(operator: 'AND', column: 'encounter.site_id', location: @location)}
|
137
|
-
WHERE obs.concept_id IN (#{pregnant_concepts.to_sql})
|
138
|
-
AND obs.obs_datetime BETWEEN DATE(#{ActiveRecord::Base.connection.quote(start_date)}) AND DATE(#{ActiveRecord::Base.connection.quote(end_date)}) + INTERVAL 1 DAY
|
139
|
-
AND obs.voided = 0
|
140
|
-
#{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
141
|
-
GROUP BY person_id
|
142
|
-
) AS max_obs ON max_obs.person_id = o.person_id AND max_obs.obs_datetime = o.obs_datetime
|
143
|
-
#{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
144
|
-
WHERE o.concept_id IN (#{pregnant_concepts.to_sql})
|
127
|
+
LEFT JOIN obs #{current_partition} a ON a.obs_id = o.obs_id and a.obs_datetime > o.obs_datetime and a.concept_id in (#{pregnant_concepts.to_sql}) and a.voided = 0
|
128
|
+
AND a.obs_datetime >= DATE(#{ActiveRecord::Base.connection.quote(start_date)}) AND a.obs_datetime < DATE(#{ActiveRecord::Base.connection.quote(end_date)}) + INTERVAL 1 DAY
|
129
|
+
WHERE a.obs_id is null
|
130
|
+
and o.obs_datetime < DATE(#{ActiveRecord::Base.connection.quote(end_date)}) + INTERVAL 1 DAY
|
145
131
|
AND o.voided = 0
|
132
|
+
AND o.concept_id in (#{pregnant_concepts.to_sql})
|
146
133
|
AND o.value_coded IN (#{yes_concepts.join(',')})
|
147
134
|
AND o.person_id IN (#{patient_list.join(',')})
|
148
|
-
#{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
149
135
|
GROUP BY o.person_id
|
150
136
|
SQL
|
151
137
|
end
|
@@ -154,27 +140,14 @@ module MalawiHivProgramReports
|
|
154
140
|
ActiveRecord::Base.connection.select_all <<~SQL
|
155
141
|
SELECT o.person_id, o.value_coded
|
156
142
|
FROM obs #{current_partition} o
|
157
|
-
|
158
|
-
#{
|
159
|
-
|
160
|
-
|
161
|
-
INNER JOIN (
|
162
|
-
SELECT person_id, MAX(obs_datetime) AS obs_datetime
|
163
|
-
FROM obs #{current_partition}
|
164
|
-
INNER JOIN encounter #{current_partition} ON encounter.encounter_id = obs.encounter_id AND encounter.encounter_type IN (#{encounter_types.to_sql}) AND encounter.voided = 0
|
165
|
-
#{site_manager(operator: 'AND', column: 'encounter.site_id', location: @location)}
|
166
|
-
WHERE obs.concept_id IN (#{breast_feeding_concepts.to_sql})
|
167
|
-
AND obs.obs_datetime BETWEEN DATE(#{ActiveRecord::Base.connection.quote(start_date)}) AND DATE(#{ActiveRecord::Base.connection.quote(end_date)}) + INTERVAL 1 DAY
|
168
|
-
AND obs.voided = 0
|
169
|
-
#{site_manager(operator: 'AND', column: 'obs.site_id', location: @location)}
|
170
|
-
GROUP BY person_id
|
171
|
-
) AS max_obs ON max_obs.person_id = o.person_id AND max_obs.obs_datetime = o.obs_datetime
|
172
|
-
#{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
173
|
-
WHERE o.concept_id IN (#{breast_feeding_concepts.to_sql})
|
143
|
+
LEFT JOIN obs #{current_partition} a ON a.obs_id = o.obs_id and a.obs_datetime > o.obs_datetime and a.concept_id in (#{breast_feeding_concepts.to_sql}) and a.voided = 0
|
144
|
+
AND a.obs_datetime >= DATE(#{ActiveRecord::Base.connection.quote(start_date)}) AND a.obs_datetime < DATE(#{ActiveRecord::Base.connection.quote(end_date)}) + INTERVAL 1 DAY
|
145
|
+
WHERE a.obs_id is null
|
146
|
+
and o.obs_datetime < DATE(#{ActiveRecord::Base.connection.quote(end_date)}) + INTERVAL 1 DAY
|
174
147
|
AND o.voided = 0
|
148
|
+
AND o.concept_id IN (#{breast_feeding_concepts.to_sql})
|
175
149
|
AND o.value_coded IN (#{yes_concepts.join(',')})
|
176
150
|
AND o.person_id IN (#{patient_list.join(',')})
|
177
|
-
#{site_manager(operator: 'AND', column: 'o.site_id', location: @location)}
|
178
151
|
GROUP BY o.person_id
|
179
152
|
SQL
|
180
153
|
end
|
@@ -191,22 +164,22 @@ module MalawiHivProgramReports
|
|
191
164
|
|
192
165
|
def refresh_outcomes_table
|
193
166
|
MalawiHivProgramReports::Moh::CohortBuilder.new(outcomes_definition: 'pepfar', location: @location)
|
194
|
-
|
167
|
+
.init_temporary_tables(@start_date, @end_date, nil)
|
195
168
|
end
|
196
169
|
|
197
170
|
def create_patients_alive_and_on_art_query
|
198
171
|
ActiveRecord::Base.connection.select_all(
|
199
172
|
<<~SQL
|
200
173
|
SELECT tpo.patient_id, LEFT(tesd.gender, 1) AS gender, disaggregated_age_group(tesd.birthdate, DATE('#{end_date.to_date}')) age_group
|
201
|
-
FROM
|
202
|
-
INNER JOIN
|
174
|
+
FROM cdr_temp_patient_outcomes #{current_partition} tpo
|
175
|
+
INNER JOIN cdr_temp_cohort_members #{current_partition} tesd ON tesd.patient_id = tpo.patient_id
|
203
176
|
WHERE tpo.cum_outcome = 'On antiretrovirals'
|
204
177
|
SQL
|
205
178
|
)
|
206
179
|
end
|
207
180
|
|
208
181
|
def load_tx_curr_into_report(report, patients)
|
209
|
-
report.
|
182
|
+
report.each_key do |age_group|
|
210
183
|
%i[M F].each do |gender|
|
211
184
|
report[age_group][gender][:tx_curr] ||= []
|
212
185
|
report[age_group][gender][:tx_curr] = populate_tx_curr(patients, age_group, gender) || []
|
@@ -217,11 +190,9 @@ module MalawiHivProgramReports
|
|
217
190
|
def populate_tx_curr(patients, age_group, gender)
|
218
191
|
patients.select do |patient|
|
219
192
|
(patient['age_group'] == age_group && patient['gender'].to_sym == gender) && patient['patient_id']
|
220
|
-
end&.map {|a| a['patient_id']}
|
193
|
+
end&.map { |a| a['patient_id'] }
|
221
194
|
end
|
222
195
|
|
223
|
-
# rubocop:disable Metrics/AbcSize
|
224
|
-
# rubocop:disable Metrics/MethodLength
|
225
196
|
def load_patient_tests_into_report(report, clients)
|
226
197
|
find_patients_with_viral_load(clients).each do |patient|
|
227
198
|
age_group = patient['age_group']
|
@@ -7,7 +7,7 @@ module MalawiHivProgramReports
|
|
7
7
|
'APPOINTMENTS' => MalawiHivProgramReports::Clinic::AppointmentsReport,
|
8
8
|
'ARV_REFILL_PERIODS' => MalawiHivProgramReports::ArvRefillPeriods,
|
9
9
|
'COHORT' => MalawiHivProgramReports::Moh::ArtCohort,
|
10
|
-
'COHORT_DISAGGREGATED' => MalawiHivProgramReports::
|
10
|
+
'COHORT_DISAGGREGATED' => MalawiHivProgramReports::Cohort::Disaggregated,
|
11
11
|
'COHORT_DISAGGREGATED_ADDITIONS' => MalawiHivProgramReports::Moh::CohortDisaggregatedAdditions,
|
12
12
|
'COHORT_SURVIVAL_ANALYSIS' => MalawiHivProgramReports::Moh::CohortSurvivalAnalysis,
|
13
13
|
'DRUG_DISPENSATIONS' => MalawiHivProgramReports::Clinic::DrugDispensations,
|
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.1.
|
4
|
+
version: 1.1.3
|
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-06-
|
11
|
+
date: 2024-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- app/services/malawi_hiv_program_reports/clinic/viral_load_results.rb
|
126
126
|
- app/services/malawi_hiv_program_reports/clinic/visits_report.rb
|
127
127
|
- app/services/malawi_hiv_program_reports/clinic/vl_collection.rb
|
128
|
+
- app/services/malawi_hiv_program_reports/cohort/disaggregated.rb
|
128
129
|
- app/services/malawi_hiv_program_reports/cohort/outcomes.rb
|
129
130
|
- app/services/malawi_hiv_program_reports/cohort/regimens.rb
|
130
131
|
- app/services/malawi_hiv_program_reports/cohort/side_effects.rb
|