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 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