malawi_hiv_program_reports 1.1.1 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af23c66f80f04922477b707fe4978ca1234e06814761e657a4e9a27c8bb433e3
4
- data.tar.gz: 762826dfec0aafbf978fc024ab7dafca271d3d6588128c9d4a9180a0ffcf86ab
3
+ metadata.gz: ed231eff9bb9c45a7d57027366c82fc112fc1de0cb6c4f457cd87bfeed1bd908
4
+ data.tar.gz: 3b9a9292285146cac5a4f202bf2d2266fdf323f1acdb67a94706efee322f4afe
5
5
  SHA512:
6
- metadata.gz: dad18495c08f5e2ca3db34adad758449cdf147dbd8c9edabbb8b771f68e0dda3d4ae88d47082a24fa5ef62f52e74f603676f8bef15d896ae93947ba529421132
7
- data.tar.gz: e3497d0e34c8397efec79d71d6e77e805b3d580e1b8096856a04a2e97d6fe7da73612bf593a58c680b13b93c73778f014d61ea3edfb5ba7fe690e31f62fbc778
6
+ metadata.gz: 2dab0b971e5a76b0097586837b7adb5869d5c0d34563824cc79d02b8cce0679f22a1afce0955b3a733663e017a6886ccced14f924dd5636f34026c05fc6649b4
7
+ data.tar.gz: 7015b44578a5bdfaea8a15c2b85b03823688b5a13fdf37e683612549c257376c0583117a28b03332d4af53c2561069c1b5d406862fd341ba15e0c724b0bbdfe7
@@ -188,7 +188,9 @@ module MalawiHivProgramReports
188
188
  end
189
189
 
190
190
  def current_partition
191
- "PARTITION (p#{@location})"
191
+ return "PARTITION (p#{@location})" unless @location.blank?
192
+
193
+ ''
192
194
  end
193
195
 
194
196
  # this is a min filter
@@ -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 = failed_locs&.map { |loc| loc[:site_id] }
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 = (name.present? && name == 'true') ? 'Filing number' : 'ARV Number'
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
- SELECT p.person_id patient_id
99
- FROM person #{current_partition} p
100
- 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
101
- 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
102
- 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
103
- LEFT JOIN (
104
- 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: '+')}
105
- ) AS new_patient ON p.person_id = new_patient.person_id
106
- LEFT JOIN (
107
- 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: '+')}
108
- ) AS refill ON p.person_id = refill.person_id
109
- LEFT JOIN (
110
- 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: '+')}
111
- ) AS external ON p.person_id = external.person_id
112
- WHERE (refill.value_coded IS NOT NULL OR external.value_coded IS NOT NULL)
113
- AND NOT (hiv_registration.encounter_id IS NOT NULL OR new_patient.value_coded IS NOT NULL)
114
- GROUP BY p.person_id
115
- ORDER BY hiv_registration.encounter_datetime DESC, refill.obs_datetime DESC, external.obs_datetime DESC
116
- SQL
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', operator: '+')}").exists?
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
- include Utils
14
- include MalawiHivProgramReports::Utils::CommonSqlQueryUtils
15
- include MalawiHivProgramReports::Adapters::Moh::Custom
16
- include MalawiHivProgramReports::Utils::ModelUtils
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.map do |patient|
58
+ @maternal_status = vl_maternal_status(results.filter_map do |patient|
60
59
  patient['patient_id'] if patient['gender'] == 'F'
61
- end.compact)
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.match(/P/i)
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
- INNER JOIN encounter #{current_partition} e ON e.encounter_id = o.encounter_id AND e.voided = 0 AND e.encounter_type IN (#{encounter_types.to_sql})
129
- #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
130
- INNER JOIN person #{current_partition} p ON o.person_id = e.patient_id AND LEFT(p.gender, 1) = 'F'
131
- #{site_manager(operator: 'AND', column: 'p.site_id', location: @location)}
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
- INNER JOIN encounter #{current_partition} e ON e.encounter_id = o.encounter_id AND e.voided = 0 AND e.encounter_type IN (#{encounter_types.to_sql})
158
- #{site_manager(operator: 'AND', column: 'e.site_id', location: @location)}
159
- INNER JOIN person #{current_partition} p ON o.person_id = e.patient_id AND LEFT(p.gender, 1) = 'F'
160
- #{site_manager(operator: 'AND', column: 'p.site_id', location: @location)}
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
- .init_temporary_tables(@start_date, @end_date, nil)
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 temp_patient_outcomes #{current_partition} tpo
202
- INNER JOIN temp_earliest_start_date #{current_partition} tesd ON tesd.patient_id = tpo.patient_id
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.each do |age_group, _data|
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::Moh::CohortDisaggregated,
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,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MalawiHivProgramReports
4
- VERSION = '1.1.1'
4
+ VERSION = '1.1.3'
5
5
  end
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.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-13 00:00:00.000000000 Z
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