malawi_hiv_program_reports 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/services/malawi_hiv_program_reports/README.md +16 -0
- data/app/services/malawi_hiv_program_reports/adapters/moh/custom.rb +199 -0
- data/app/services/malawi_hiv_program_reports/archiving_candidates.rb +130 -0
- data/app/services/malawi_hiv_program_reports/arv_refill_periods.rb +311 -0
- data/app/services/malawi_hiv_program_reports/clinic/README.md +5 -0
- data/app/services/malawi_hiv_program_reports/clinic/appointments_report.rb +317 -0
- data/app/services/malawi_hiv_program_reports/clinic/discrepancy_report.rb +42 -0
- data/app/services/malawi_hiv_program_reports/clinic/docs/hypertension_report.md +31 -0
- data/app/services/malawi_hiv_program_reports/clinic/drug_dispensations.rb +48 -0
- data/app/services/malawi_hiv_program_reports/clinic/external_consultation_clients.rb +69 -0
- data/app/services/malawi_hiv_program_reports/clinic/hypertension_report.rb +223 -0
- data/app/services/malawi_hiv_program_reports/clinic/ipt_coverage.rb +112 -0
- data/app/services/malawi_hiv_program_reports/clinic/ipt_report.rb +69 -0
- data/app/services/malawi_hiv_program_reports/clinic/lims_results.rb +55 -0
- data/app/services/malawi_hiv_program_reports/clinic/outcome_list.rb +127 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_alive_and_on_treatment.rb +57 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_due_for_viral_load.rb +39 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_on_antiretrovirals.rb +44 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_on_dtg.rb +36 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_on_treatment.rb +42 -0
- data/app/services/malawi_hiv_program_reports/clinic/patients_with_outdated_demographics.rb +173 -0
- data/app/services/malawi_hiv_program_reports/clinic/pregnant_patients.rb +91 -0
- data/app/services/malawi_hiv_program_reports/clinic/regimen_dispensation_data.rb +282 -0
- data/app/services/malawi_hiv_program_reports/clinic/regimen_switch.rb +456 -0
- data/app/services/malawi_hiv_program_reports/clinic/regimens_and_formulations.rb +182 -0
- data/app/services/malawi_hiv_program_reports/clinic/regimens_by_weight_and_gender.rb +108 -0
- data/app/services/malawi_hiv_program_reports/clinic/retention.rb +246 -0
- data/app/services/malawi_hiv_program_reports/clinic/stock_card_report.rb +65 -0
- data/app/services/malawi_hiv_program_reports/clinic/tpt_outcome.rb +494 -0
- data/app/services/malawi_hiv_program_reports/clinic/tx_rtt.rb +169 -0
- data/app/services/malawi_hiv_program_reports/clinic/viral_load.rb +292 -0
- data/app/services/malawi_hiv_program_reports/clinic/viral_load_disaggregated.rb +97 -0
- data/app/services/malawi_hiv_program_reports/clinic/viral_load_results.rb +175 -0
- data/app/services/malawi_hiv_program_reports/clinic/visits_report.rb +113 -0
- data/app/services/malawi_hiv_program_reports/clinic/vl_collection.rb +48 -0
- data/app/services/malawi_hiv_program_reports/cohort/outcomes.rb +338 -0
- data/app/services/malawi_hiv_program_reports/cohort/regimens.rb +69 -0
- data/app/services/malawi_hiv_program_reports/cohort/side_effects.rb +141 -0
- data/app/services/malawi_hiv_program_reports/cohort/tpt.rb +172 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort.rb +278 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_builder.rb +2340 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated.rb +608 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated_additions.rb +208 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_disaggregated_builder.rb +526 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_struct.rb +219 -0
- data/app/services/malawi_hiv_program_reports/moh/cohort_survival_analysis.rb +203 -0
- data/app/services/malawi_hiv_program_reports/moh/moh_tpt.rb +223 -0
- data/app/services/malawi_hiv_program_reports/moh/tpt_newly_initiated.rb +235 -0
- data/app/services/malawi_hiv_program_reports/pepfar/defaulter_list.rb +25 -0
- data/app/services/malawi_hiv_program_reports/pepfar/maternal_status.rb +29 -0
- data/app/services/malawi_hiv_program_reports/pepfar/patient_start_vl.rb +45 -0
- data/app/services/malawi_hiv_program_reports/pepfar/regimen_switch.rb +479 -0
- data/app/services/malawi_hiv_program_reports/pepfar/sc_arvdisp.rb +174 -0
- data/app/services/malawi_hiv_program_reports/pepfar/sc_curr.rb +98 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tb_prev.rb +163 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tb_prev2.rb +222 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tb_prev3.rb +421 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tpt_status.rb +181 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tx_ml.rb +181 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tx_new.rb +202 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tx_rtt.rb +288 -0
- data/app/services/malawi_hiv_program_reports/pepfar/tx_tb.rb +283 -0
- data/app/services/malawi_hiv_program_reports/pepfar/utils.rb +141 -0
- data/app/services/malawi_hiv_program_reports/pepfar/viral_load_coverage.rb +414 -0
- data/app/services/malawi_hiv_program_reports/pepfar/viral_load_coverage2.rb +433 -0
- data/app/services/malawi_hiv_program_reports/report_map.rb +56 -0
- data/app/services/malawi_hiv_program_reports/utils/README.md +8 -0
- data/app/services/malawi_hiv_program_reports/utils/common_sql_query_utils.rb +60 -0
- data/app/services/malawi_hiv_program_reports/utils/concurrency_utils.rb +53 -0
- data/app/services/malawi_hiv_program_reports/utils/docs/common_sql_query_utils.md +53 -0
- data/app/services/malawi_hiv_program_reports/utils/model_utils.rb +66 -0
- data/app/services/malawi_hiv_program_reports/utils/parameter_utils.rb +32 -0
- data/app/services/malawi_hiv_program_reports/utils/time_utils.rb +52 -0
- data/lib/malawi_hiv_program_reports/version.rb +1 -1
- metadata +74 -1
@@ -0,0 +1,235 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MalawiHivProgramReports
|
4
|
+
module Moh
|
5
|
+
##
|
6
|
+
# Patients newly initiated on TPT disaggregated by regimen type and age group.
|
7
|
+
#
|
8
|
+
# Newly initiated is defined as patients who have received TPT for the first
|
9
|
+
# time in the reporting period or patients who have gone on a TPT course
|
10
|
+
# break for a period that is at least 9 months long before restarting TPT
|
11
|
+
# in the current reporting period.
|
12
|
+
# rubocop:disable Metrics/ClassLength
|
13
|
+
class TptNewlyInitiated
|
14
|
+
attr_reader :start_date, :end_date
|
15
|
+
|
16
|
+
def initialize(start_date:, end_date:, **kwargs)
|
17
|
+
@start_date = ActiveRecord::Base.connection.quote(start_date)
|
18
|
+
@end_date = ActiveRecord::Base.connection.quote(end_date)
|
19
|
+
@occupation = kwargs[:occupation]
|
20
|
+
@location = kwargs[:location]
|
21
|
+
@adapter = ActiveRecord::Base.connection.adapter_name.downcase
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_report
|
25
|
+
report = init_report
|
26
|
+
newly_initiated_on_tpt.each do |tpt, patients|
|
27
|
+
patients.each do |patient|
|
28
|
+
patient_id = patient['patient_id']
|
29
|
+
person = ActiveRecord::Base.connection.select_one <<~SQL
|
30
|
+
SELECT disaggregated_age_group(birthdate, DATE('#{end_date.to_date}')) AS age_group,
|
31
|
+
patient_identifier.identifier AS arv_number, person.*
|
32
|
+
FROM person
|
33
|
+
LEFT JOIN patient_identifier ON patient_identifier.patient_id = person.person_id
|
34
|
+
AND patient_identifier.identifier_type IN (SELECT patient_identifier_type_id FROM patient_identifier_type
|
35
|
+
WHERE name = 'ARV Number') AND patient_identifier.voided = 0
|
36
|
+
WHERE person_id = #{patient_id} LIMIT 1;
|
37
|
+
SQL
|
38
|
+
age_group = person['age_group']
|
39
|
+
gender = person['gender']&.strip&.first&.upcase || 'Unknown'
|
40
|
+
# course = patient_on_3hp?(patient) ? '3HP' : '6H'
|
41
|
+
|
42
|
+
report[age_group][tpt][gender] << {
|
43
|
+
patient_id: person['person_id'],
|
44
|
+
birthdate: person['birthdate'],
|
45
|
+
arv_number: person['arv_number'],
|
46
|
+
gender:,
|
47
|
+
dispensation_date: dispensation_date(patient_id, patient['drug_concepts']),
|
48
|
+
art_start_date: patient['earliest_start_date'],
|
49
|
+
tpt_start_date: patient['tpt_start_date']
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
report['Location'] = Location.current.city_village
|
54
|
+
report
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
AGE_GROUPS = [
|
60
|
+
'Unknown',
|
61
|
+
'<1 year',
|
62
|
+
'1-4 years', '5-9 years',
|
63
|
+
'10-14 years', '15-19 years',
|
64
|
+
'20-24 years',
|
65
|
+
'25-29 years', '30-34 years',
|
66
|
+
'35-39 years', '40-44 years',
|
67
|
+
'45-49 years', '50-54 years',
|
68
|
+
'55-59 years', '60-64 years',
|
69
|
+
'65-69 years', '70-74 years',
|
70
|
+
'75-79 years', '80-84 years',
|
71
|
+
'85-89 years',
|
72
|
+
'90 plus years'
|
73
|
+
].freeze
|
74
|
+
|
75
|
+
def dispensation_date(patient_id, concept_ids)
|
76
|
+
order = ActiveRecord::Base.connection.select_one <<~SQL
|
77
|
+
SELECT MIN(orders.start_date) start_date FROM orders
|
78
|
+
INNER JOIN drug_order
|
79
|
+
ON drug_order.order_id = orders.order_id
|
80
|
+
AND drug_order.quantity > 0 /* This implies that a dispensation was made */
|
81
|
+
INNER JOIN drug
|
82
|
+
ON drug.drug_id = drug_order.drug_inventory_id
|
83
|
+
AND drug.concept_id IN(#{concept_ids})
|
84
|
+
INNER JOIN encounter ON encounter.encounter_id = orders.encounter_id
|
85
|
+
AND encounter.program_id = 1
|
86
|
+
WHERE DATE(orders.start_date) BETWEEN '#{start_date.to_date}' AND '#{end_date.to_date}'
|
87
|
+
AND orders.voided = 0 AND orders.patient_id = #{patient_id};
|
88
|
+
SQL
|
89
|
+
|
90
|
+
order['start_date'].to_date
|
91
|
+
end
|
92
|
+
|
93
|
+
def init_report
|
94
|
+
AGE_GROUPS.each_with_object({}) do |age_group, report|
|
95
|
+
report[age_group] = {
|
96
|
+
'3HP_new' => { 'M' => [], 'F' => [], 'Unknown' => [] },
|
97
|
+
'6H_new' => { 'M' => [], 'F' => [], 'Unknown' => [] },
|
98
|
+
'3HP_prev' => { 'M' => [], 'F' => [], 'Unknown' => [] },
|
99
|
+
'6H_prev' => { 'M' => [], 'F' => [], 'Unknown' => [] }
|
100
|
+
}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def patient_on_3hp?(patient)
|
105
|
+
patient['drug_concepts'].split(',').collect(&:to_i).include?(rifapentine_concept.concept_id)
|
106
|
+
end
|
107
|
+
|
108
|
+
def rifapentine_concept
|
109
|
+
@rifapentine_concept ||= ::ConceptName.find_by!(name: 'Rifapentine')
|
110
|
+
end
|
111
|
+
|
112
|
+
def newly_initiated_on_tpt
|
113
|
+
tpt = Cohort::Tpt.new(start_date: start_date.to_date, end_date: end_date.to_date, occupation: @occupation,
|
114
|
+
location: @location)
|
115
|
+
data = {}
|
116
|
+
three_hp = tpt.newly_initiated_on_3hp
|
117
|
+
ipt = tpt.newly_initiated_on_ipt
|
118
|
+
data['3HP_new'] = three_hp.select do |record|
|
119
|
+
record['earliest_start_date'].to_date > end_date.to_date - 3.month
|
120
|
+
end
|
121
|
+
data['6H_new'] = ipt.select { |record| record['earliest_start_date'].to_date > end_date.to_date - 3.month }
|
122
|
+
data['3HP_prev'] = three_hp.select do |record|
|
123
|
+
record['earliest_start_date'].to_date <= end_date.to_date - 3.month
|
124
|
+
end
|
125
|
+
data['6H_prev'] = ipt.select { |record| record['earliest_start_date'].to_date <= end_date.to_date - 3.month }
|
126
|
+
data
|
127
|
+
end
|
128
|
+
|
129
|
+
def newly_initiated_on_tpt_old
|
130
|
+
ActiveRecord::Base.connection.select_all <<~SQL
|
131
|
+
SELECT patient_program.patient_id,
|
132
|
+
disaggregated_age_group(person.birthdate, DATE(#{end_date})) AS age_group,
|
133
|
+
DATE(prescription_encounter.encounter_datetime) AS prescription_date,
|
134
|
+
person_name.given_name,
|
135
|
+
person_name.family_name,
|
136
|
+
person.birthdate,
|
137
|
+
person.gender,
|
138
|
+
patient_identifier.identifier AS arv_number,
|
139
|
+
GROUP_CONCAT(DISTINCT orders.concept_id SEPARATOR ',') AS drug_concepts
|
140
|
+
FROM person
|
141
|
+
LEFT JOIN person_name
|
142
|
+
ON person_name.person_id = person.person_id
|
143
|
+
AND person_name.voided = 0
|
144
|
+
LEFT JOIN patient_identifier
|
145
|
+
ON patient_identifier.patient_id = person.person_id
|
146
|
+
AND patient_identifier.identifier_type IN (SELECT patient_identifier_type_id FROM patient_identifier_type WHERE name = 'ARV Number')
|
147
|
+
AND patient_identifier.voided = 0
|
148
|
+
INNER JOIN patient_program
|
149
|
+
ON patient_program.patient_id = person.person_id
|
150
|
+
AND patient_program.program_id IN (SELECT program_id FROM program WHERE name = 'HIV PROGRAM')
|
151
|
+
INNER JOIN encounter AS prescription_encounter
|
152
|
+
ON prescription_encounter.patient_id = person.person_id
|
153
|
+
AND prescription_encounter.encounter_type IN (SELECT encounter_type_id FROM encounter_type WHERE name = 'Treatment')
|
154
|
+
AND prescription_encounter.program_id IN (SELECT program_id FROM program WHERE name = 'HIV PROGRAM')
|
155
|
+
AND prescription_encounter.encounter_datetime >= #{start_date}
|
156
|
+
AND prescription_encounter.encounter_datetime < DATE(#{end_date}) + INTERVAL 1 DAY
|
157
|
+
AND prescription_encounter.voided = 0
|
158
|
+
INNER JOIN orders AS orders
|
159
|
+
ON orders.encounter_id = prescription_encounter.encounter_id
|
160
|
+
AND orders.order_type_id = (SELECT order_type_id FROM order_type WHERE name = 'Drug order' LIMIT 1)
|
161
|
+
AND orders.start_date >= #{start_date}
|
162
|
+
AND orders.start_date < DATE(#{end_date}) + INTERVAL 1 DAY
|
163
|
+
AND orders.voided = 0
|
164
|
+
INNER JOIN drug_order
|
165
|
+
ON drug_order.order_id = orders.order_id
|
166
|
+
AND drug_order.quantity > 0 /* This implies that a dispensation was made */
|
167
|
+
INNER JOIN drug
|
168
|
+
ON drug.drug_id = drug_order.drug_inventory_id
|
169
|
+
INNER JOIN concept_name AS tpt_drug_concepts
|
170
|
+
ON tpt_drug_concepts.concept_id = drug.concept_id
|
171
|
+
AND tpt_drug_concepts.name IN ('Rifapentine', 'Isoniazid')
|
172
|
+
AND tpt_drug_concepts.voided = 0
|
173
|
+
WHERE patient_program.patient_id NOT IN (
|
174
|
+
/* Filter out patients who received TPT before current reporting period */
|
175
|
+
SELECT DISTINCT patient_program.patient_id
|
176
|
+
FROM patient_program
|
177
|
+
INNER JOIN encounter AS prescription_encounter
|
178
|
+
ON prescription_encounter.patient_id = patient_program.patient_id
|
179
|
+
AND prescription_encounter.encounter_type IN (SELECT encounter_type_id FROM encounter_type WHERE name = 'Treatment')
|
180
|
+
AND prescription_encounter.program_id = (SELECT program_id FROM program WHERE name = 'HIV PROGRAM' LIMIT 1)
|
181
|
+
AND prescription_encounter.voided = 0
|
182
|
+
INNER JOIN orders
|
183
|
+
ON orders.encounter_id = prescription_encounter.encounter_id
|
184
|
+
AND orders.order_type_id = (SELECT order_type_id FROM order_type WHERE name = 'Drug order' LIMIT 1)
|
185
|
+
AND orders.start_date < #{start_date}
|
186
|
+
/* Re-initiates defined as those who stopped TPT for a period of at least 9 months
|
187
|
+
and have restarted TPT are also included in the report */
|
188
|
+
AND orders.start_date >= DATE(#{start_date}) - INTERVAL 9 MONTH
|
189
|
+
AND orders.voided = 0
|
190
|
+
INNER JOIN concept_name AS tpt_drug_concepts
|
191
|
+
ON tpt_drug_concepts.concept_id = orders.concept_id
|
192
|
+
AND tpt_drug_concepts.name IN ('Rifapentine', 'Isoniazid')
|
193
|
+
AND tpt_drug_concepts.voided = 0
|
194
|
+
INNER JOIN drug_order AS drug_order
|
195
|
+
ON drug_order.order_id = orders.order_id
|
196
|
+
AND drug_order.quantity > 0
|
197
|
+
WHERE patient_program.program_id IN (SELECT program_id FROM program WHERE name = 'HIV PROGRAM')
|
198
|
+
) AND patient_program.patient_id NOT IN (
|
199
|
+
/* External consultations */
|
200
|
+
SELECT DISTINCT registration_encounter.patient_id
|
201
|
+
FROM patient_program
|
202
|
+
INNER JOIN program ON program.name = 'HIV PROGRAM'
|
203
|
+
INNER JOIN encounter AS registration_encounter
|
204
|
+
ON registration_encounter.patient_id = patient_program.patient_id
|
205
|
+
AND registration_encounter.program_id = patient_program.program_id
|
206
|
+
AND registration_encounter.encounter_datetime < DATE(#{end_date}) + INTERVAL 1 DAY
|
207
|
+
AND registration_encounter.voided = 0
|
208
|
+
INNER JOIN (
|
209
|
+
SELECT MAX(encounter.encounter_datetime) AS encounter_datetime, encounter.patient_id
|
210
|
+
FROM encounter
|
211
|
+
INNER JOIN encounter_type
|
212
|
+
ON encounter_type.encounter_type_id = encounter.encounter_type
|
213
|
+
AND encounter_type.name = 'Registration'
|
214
|
+
INNER JOIN program
|
215
|
+
ON program.program_id = encounter.program_id
|
216
|
+
AND program.name = 'HIV PROGRAM'
|
217
|
+
WHERE encounter.encounter_datetime < DATE(#{end_date}) AND encounter.voided = 0
|
218
|
+
GROUP BY encounter.patient_id
|
219
|
+
) AS max_registration_encounter
|
220
|
+
ON max_registration_encounter.patient_id = registration_encounter.patient_id
|
221
|
+
AND max_registration_encounter.encounter_datetime = registration_encounter.encounter_datetime
|
222
|
+
INNER JOIN obs AS patient_type_obs
|
223
|
+
ON patient_type_obs.encounter_id = registration_encounter.encounter_id
|
224
|
+
AND patient_type_obs.concept_id IN (SELECT concept_id FROM concept_name WHERE name = 'Type of patient' AND voided = 0)
|
225
|
+
AND patient_type_obs.value_coded IN (SELECT concept_id FROM concept_name WHERE name IN ('Drug refill', 'External consultation') AND voided = 0)
|
226
|
+
AND patient_type_obs.voided = 0
|
227
|
+
WHERE patient_program.voided = 0
|
228
|
+
)
|
229
|
+
GROUP BY patient_program.patient_id
|
230
|
+
SQL
|
231
|
+
end
|
232
|
+
end
|
233
|
+
# rubocop:enable Metrics/ClassLength
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MalawiHivProgramReports
|
2
|
+
module Pepfar
|
3
|
+
class DefaulterList
|
4
|
+
|
5
|
+
attr_reader :start_date, :end_date, :location
|
6
|
+
|
7
|
+
def initialize(start_date:, end_date:, **kwargs)
|
8
|
+
@start_date = start_date
|
9
|
+
@end_date = end_date
|
10
|
+
@location = kwargs[:location]
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_report
|
14
|
+
MalawiHivProgramReports::Moh::Cohort.new(
|
15
|
+
type: 'defaulter_list',
|
16
|
+
location: @location,
|
17
|
+
name: 'defaulter_list',
|
18
|
+
start_date: start_date,
|
19
|
+
end_date: end_date
|
20
|
+
).defaulter_list('pepfar')
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module MalawiHivProgramReports
|
2
|
+
module Pepfar
|
3
|
+
# rubocop:disable Metrics/ClassLength
|
4
|
+
class MaternalStatus
|
5
|
+
include Utils
|
6
|
+
include MalawiHivProgramReports::Utils::CommonSqlQueryUtils
|
7
|
+
include MalawiHivProgramReports::Adapters::Moh::Custom
|
8
|
+
include MalawiHivProgramReports::Utils::ModelUtils
|
9
|
+
attr_reader :start_date, :end_date, :location
|
10
|
+
|
11
|
+
def initialize(start_date:, end_date:, **kwargs)
|
12
|
+
@start_date = start_date&.to_date
|
13
|
+
raise InvalidParameterError, 'start_date is required' unless @start_date
|
14
|
+
|
15
|
+
@end_date = end_date&.to_date || @start_date + 12.months
|
16
|
+
raise InvalidParameterError, "start_date can't be greater than end_date" if @start_date > @end_date
|
17
|
+
|
18
|
+
@occupation = kwargs.delete(:occupation)
|
19
|
+
@type = kwargs.delete(:application)
|
20
|
+
@location = kwargs.delete(:location)
|
21
|
+
@patient_ids = kwargs.delete(:patient_ids)&.split(',') || []
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_report
|
25
|
+
MalawiHivProgramReports::Pepfar::ViralLoadCoverage2.new(tx_curr_definition: 'pepfar', start_date: @start_date, end_date: @end_date, location: @location).vl_maternal_status(@patient_ids)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MalawiHivProgramReports
|
4
|
+
module Pepfar
|
5
|
+
# this module returns all the patient records on when
|
6
|
+
# when the patient started ART
|
7
|
+
# plus the last viral load result
|
8
|
+
class PatientStartVl
|
9
|
+
|
10
|
+
attr_reader :start_date, :end_date, :location, :patient_ids
|
11
|
+
|
12
|
+
include Utils
|
13
|
+
include MalawiHivProgramReports::Adapters::Moh::Custom
|
14
|
+
|
15
|
+
def initialize(start_date:, end_date:, **kwargs)
|
16
|
+
@start_date = start_date
|
17
|
+
@end_date = end_date
|
18
|
+
@location = kwargs[:location]
|
19
|
+
@patient_ids = kwargs[:patient_ids]
|
20
|
+
raise InvalidParameterError, 'Patient IDs are required' if patient_ids.blank?
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_report
|
24
|
+
get_patients_last_vl_and_latest_result
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_patients_last_vl_and_latest_result
|
28
|
+
ids = patient_ids.split(',')
|
29
|
+
ActiveRecord::Base.connection.select_all <<~SQL
|
30
|
+
SELECT p.person_id AS patient_id,
|
31
|
+
patient_start_date(p.person_id) AS art_start_date,
|
32
|
+
p.birthdate AS birthdate,
|
33
|
+
p.gender,
|
34
|
+
MIN(pi.identifier)
|
35
|
+
FROM person p
|
36
|
+
LEFT JOIN patient_identifier pi ON pi.patient_id = p.person_id AND pi.voided = 0 AND pi.identifier_type = 4
|
37
|
+
WHERE p.voided = 0
|
38
|
+
AND #{in_manager(column: 'p.person_id', values: ids)}
|
39
|
+
#{site_manager(operator: 'AND', column: 'p.site_id', location: location)}
|
40
|
+
GROUP BY p.person_id, p.birthdate, p.gender
|
41
|
+
SQL
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|