diff --git a/app/models/reports/overdue_patient.rb b/app/models/reports/overdue_patient.rb index e8b65fea1c..b18c487a94 100644 --- a/app/models/reports/overdue_patient.rb +++ b/app/models/reports/overdue_patient.rb @@ -4,7 +4,7 @@ class OverduePatient < Reports::View belongs_to :patient def self.materialized? - true + false end def self.partitioned? diff --git a/db/migrate/20260521101357_discard_mat_view_reporting_overdue_patients.rb b/db/migrate/20260521101357_discard_mat_view_reporting_overdue_patients.rb new file mode 100644 index 0000000000..3dd9aa209f --- /dev/null +++ b/db/migrate/20260521101357_discard_mat_view_reporting_overdue_patients.rb @@ -0,0 +1,238 @@ +class DiscardMatViewReportingOverduePatients < ActiveRecord::Migration[6.1] + def up + drop_view :reporting_overdue_patients, materialized: true + + execute <<~SQL + CREATE VIEW public.reporting_overdue_patients AS SELECT * FROM simple_reporting.reporting_overdue_patients; + SQL + end + + def down + drop_view :reporting_overdue_patients + + execute <<~SQL + CREATE MATERIALIZED VIEW public.reporting_overdue_patients AS + WITH patients_with_appointments AS ( + SELECT DISTINCT ON (rps.patient_id, rps.month_date) + rps.month_date, + rps.patient_id, + rps.hypertension AS hypertension, + rps.diabetes AS diabetes, + rps.htn_care_state, + rps.month, + rps.quarter, + rps.year, + rps.month_string, + rps.quarter_string, + rps.assigned_facility_id, + rps.assigned_facility_slug, + rps.assigned_facility_region_id, + rps.assigned_block_slug, + rps.assigned_block_region_id, + rps.assigned_district_slug, + rps.assigned_district_region_id, + rps.assigned_state_slug, + rps.assigned_state_region_id, + rps.assigned_organization_slug, + rps.assigned_organization_region_id, + appointments.id AS previous_appointment_id, + appointments.device_created_at AS previous_appointment_date, + appointments.scheduled_date AS previous_appointment_schedule_date + FROM + reporting_patient_states rps + LEFT JOIN appointments ON appointments.patient_id = rps.patient_id + AND appointments.device_created_at < rps.month_date + WHERE + rps.status <> 'dead' + AND rps.month_date > NOW() - INTERVAL '24 months' + ORDER BY + rps.patient_id, + rps.month_date, + appointments.device_created_at DESC + ), + patients_with_appointments_and_visits AS ( + SELECT + patients_with_appointments.*, + visit_id, + visited_at_after_appointment + FROM + patients_with_appointments + LEFT JOIN lateral ( + SELECT DISTINCT ON (patient_id) id AS visit_id, + patient_id, + recorded_at AS visited_at_after_appointment + FROM + blood_sugars + WHERE + deleted_at IS NULL + AND patient_id = patients_with_appointments.patient_id + AND patients_with_appointments.previous_appointment_date < blood_sugars.recorded_at + AND blood_sugars.recorded_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' + UNION ALL ( + SELECT + id AS visit_id, + patient_id, + recorded_at AS visited_at_after_appointment + FROM + blood_pressures + WHERE + deleted_at IS NULL + AND patient_id = patients_with_appointments.patient_id + AND patients_with_appointments.previous_appointment_date < blood_pressures.recorded_at + AND blood_pressures.recorded_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' + ) + UNION ALL ( + SELECT + id AS visit_id, + patient_id, + device_created_at AS visited_at_after_appointment + FROM + appointments AS patients_with_appointments_visit + WHERE + deleted_at IS NULL + AND patient_id = patients_with_appointments.patient_id + AND patients_with_appointments.previous_appointment_date < patients_with_appointments_visit.device_created_at + AND patients_with_appointments_visit.device_created_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' + ) + UNION ALL ( + SELECT + id AS visit_id, + patient_id, + device_created_at AS visited_at_after_appointment + FROM + prescription_drugs + WHERE + deleted_at IS NULL + AND patient_id = patients_with_appointments.patient_id + AND patients_with_appointments.previous_appointment_date < prescription_drugs.device_created_at + AND prescription_drugs.device_created_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' + ) + ORDER BY + patient_id, + visited_at_after_appointment + ) AS visits ON patients_with_appointments.patient_id = visits.patient_id + ), + patient_with_call_results AS ( + SELECT + DISTINCT ON ( + patients_with_appointments_and_visits.patient_id, + patients_with_appointments_and_visits.month_date + ) patients_with_appointments_and_visits.*, + previous_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE 'UTC' AS previous_called_at, + previous_call_results.result_type AS previous_call_result_type, + previous_call_results.remove_reason AS previous_call_removed_from_overdue_list_reason, + next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE 'UTC' AS next_called_at, + next_call_results.result_type AS next_call_result_type, + next_call_results.remove_reason as next_call_removed_from_overdue_list_reason, + next_call_results.user_id AS called_by_user_id + FROM + patients_with_appointments_and_visits + LEFT JOIN call_results previous_call_results ON patients_with_appointments_and_visits.patient_id = previous_call_results.patient_id + AND previous_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE (SELECT current_setting('TIMEZONE')) < patients_with_appointments_and_visits.month_date + AND previous_call_results.device_created_at > previous_appointment_schedule_date + LEFT JOIN call_results next_call_results ON patients_with_appointments_and_visits.patient_id = next_call_results.patient_id + AND next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE (SELECT current_setting('TIMEZONE')) >= patients_with_appointments_and_visits.month_date + AND next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE (SELECT current_setting('TIMEZONE')) < patients_with_appointments_and_visits.month_date + INTERVAL '1 month' + ORDER BY + patients_with_appointments_and_visits.patient_id, + patients_with_appointments_and_visits.month_date, + next_call_results.device_created_at, + previous_call_results.device_created_at DESC + ), + patient_with_call_results_and_phone AS ( + SELECT + DISTINCT ON ( + patient_with_call_results.patient_id, + patient_with_call_results.month_date + ) patient_with_call_results.*, + patient_phone_numbers.number AS patient_phone_number + FROM + patient_with_call_results + LEFT JOIN patient_phone_numbers ON patient_phone_numbers.patient_id = patient_with_call_results.patient_id + ORDER BY + patient_with_call_results.patient_id, + patient_with_call_results.month_date + ) + SELECT + month_date, + patient_id, + hypertension, + diabetes, + htn_care_state, + month, + quarter, + year, + month_string, + quarter_string, + assigned_facility_id, + assigned_facility_slug, + assigned_facility_region_id, + assigned_block_slug, + assigned_block_region_id, + assigned_district_slug, + assigned_district_region_id, + assigned_state_slug, + assigned_state_region_id, + assigned_organization_slug, + assigned_organization_region_id, + previous_appointment_id, + previous_appointment_date, + previous_appointment_schedule_date, + visited_at_after_appointment, + called_by_user_id, + next_called_at, + previous_called_at, + next_call_result_type, + next_call_removed_from_overdue_list_reason, + previous_call_result_type, + previous_call_removed_from_overdue_list_reason, + CASE + WHEN previous_appointment_id IS NULL THEN 'no' + WHEN (previous_appointment_schedule_date >= month_date) THEN 'no' + WHEN ( + previous_appointment_schedule_date < month_date + and visited_at_after_appointment < month_date + ) THEN 'no' + ELSE 'yes' + END AS is_overdue, + CASE + WHEN next_called_at IS NULL THEN 'no' + ELSE 'yes' + END AS has_called, + CASE + WHEN visited_at_after_appointment IS NULL + OR next_called_at IS NULL THEN 'no' + WHEN visited_at_after_appointment > next_called_at + INTERVAL '15 days' THEN 'no' + ELSE 'yes' + END AS has_visited_following_call, + CASE + WHEN htn_care_state = 'lost_to_follow_up' THEN 'yes' + ELSE 'no' + END AS ltfu, + CASE + WHEN htn_care_state = 'under_care' THEN 'yes' + ELSE 'no' + END AS under_care, + CASE + WHEN patient_phone_number IS NULL THEN 'no' + ELSE 'yes' + END AS has_phone, + CASE + WHEN previous_call_result_type = 'removed_from_overdue_list' THEN 'yes' + ELSE 'no' + END AS removed_from_overdue_list, + CASE + WHEN next_call_result_type = 'removed_from_overdue_list' THEN 'yes' + ELSE 'no' + END AS removed_from_overdue_list_during_the_month + FROM + patient_with_call_results_and_phone + WITH NO DATA; + SQL + + execute <<~SQL + CREATE INDEX overdue_patients_assigned_facility_region_id ON public.reporting_overdue_patients USING btree (assigned_facility_region_id); + CREATE UNIQUE INDEX overdue_patients_month_date_patient_id ON public.reporting_overdue_patients USING btree (month_date, patient_id); + SQL + end +end diff --git a/db/structure.sql b/db/structure.sql index 6ef7b6c365..cdbad417ba 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -5581,238 +5581,10 @@ CREATE MATERIALIZED VIEW public.reporting_overdue_calls AS -- --- Name: reporting_overdue_patients; Type: MATERIALIZED VIEW; Schema: public; Owner: - +-- Name: reporting_overdue_patients; Type: VIEW; Schema: public; Owner: - -- -CREATE MATERIALIZED VIEW public.reporting_overdue_patients AS - WITH patients_with_appointments AS ( - SELECT DISTINCT ON (rps.patient_id, rps.month_date) rps.month_date, - rps.patient_id, - rps.hypertension, - rps.diabetes, - rps.htn_care_state, - rps.month, - rps.quarter, - rps.year, - rps.month_string, - rps.quarter_string, - rps.assigned_facility_id, - rps.assigned_facility_slug, - rps.assigned_facility_region_id, - rps.assigned_block_slug, - rps.assigned_block_region_id, - rps.assigned_district_slug, - rps.assigned_district_region_id, - rps.assigned_state_slug, - rps.assigned_state_region_id, - rps.assigned_organization_slug, - rps.assigned_organization_region_id, - appointments.id AS previous_appointment_id, - appointments.device_created_at AS previous_appointment_date, - appointments.scheduled_date AS previous_appointment_schedule_date - FROM (public.reporting_patient_states rps - LEFT JOIN public.appointments ON (((appointments.patient_id = rps.patient_id) AND (appointments.device_created_at < rps.month_date)))) - WHERE (((rps.status)::text <> 'dead'::text) AND (rps.month_date > (now() - '2 years'::interval))) - ORDER BY rps.patient_id, rps.month_date, appointments.device_created_at DESC - ), patients_with_appointments_and_visits AS ( - SELECT patients_with_appointments.month_date, - patients_with_appointments.patient_id, - patients_with_appointments.hypertension, - patients_with_appointments.diabetes, - patients_with_appointments.htn_care_state, - patients_with_appointments.month, - patients_with_appointments.quarter, - patients_with_appointments.year, - patients_with_appointments.month_string, - patients_with_appointments.quarter_string, - patients_with_appointments.assigned_facility_id, - patients_with_appointments.assigned_facility_slug, - patients_with_appointments.assigned_facility_region_id, - patients_with_appointments.assigned_block_slug, - patients_with_appointments.assigned_block_region_id, - patients_with_appointments.assigned_district_slug, - patients_with_appointments.assigned_district_region_id, - patients_with_appointments.assigned_state_slug, - patients_with_appointments.assigned_state_region_id, - patients_with_appointments.assigned_organization_slug, - patients_with_appointments.assigned_organization_region_id, - patients_with_appointments.previous_appointment_id, - patients_with_appointments.previous_appointment_date, - patients_with_appointments.previous_appointment_schedule_date, - visits.visit_id, - visits.visited_at_after_appointment - FROM (patients_with_appointments - LEFT JOIN LATERAL ( SELECT DISTINCT ON (blood_sugars.patient_id) blood_sugars.id AS visit_id, - blood_sugars.patient_id, - blood_sugars.recorded_at AS visited_at_after_appointment - FROM public.blood_sugars - WHERE ((blood_sugars.deleted_at IS NULL) AND (blood_sugars.patient_id = patients_with_appointments.patient_id) AND (patients_with_appointments.previous_appointment_date < blood_sugars.recorded_at) AND (blood_sugars.recorded_at < ((patients_with_appointments.month_date + '1 mon'::interval) + '15 days'::interval))) - UNION ALL - SELECT blood_pressures.id AS visit_id, - blood_pressures.patient_id, - blood_pressures.recorded_at AS visited_at_after_appointment - FROM public.blood_pressures - WHERE ((blood_pressures.deleted_at IS NULL) AND (blood_pressures.patient_id = patients_with_appointments.patient_id) AND (patients_with_appointments.previous_appointment_date < blood_pressures.recorded_at) AND (blood_pressures.recorded_at < ((patients_with_appointments.month_date + '1 mon'::interval) + '15 days'::interval))) - UNION ALL - SELECT patients_with_appointments_visit.id AS visit_id, - patients_with_appointments_visit.patient_id, - patients_with_appointments_visit.device_created_at AS visited_at_after_appointment - FROM public.appointments patients_with_appointments_visit - WHERE ((patients_with_appointments_visit.deleted_at IS NULL) AND (patients_with_appointments_visit.patient_id = patients_with_appointments.patient_id) AND (patients_with_appointments.previous_appointment_date < patients_with_appointments_visit.device_created_at) AND (patients_with_appointments_visit.device_created_at < ((patients_with_appointments.month_date + '1 mon'::interval) + '15 days'::interval))) - UNION ALL - SELECT prescription_drugs.id AS visit_id, - prescription_drugs.patient_id, - prescription_drugs.device_created_at AS visited_at_after_appointment - FROM public.prescription_drugs - WHERE ((prescription_drugs.deleted_at IS NULL) AND (prescription_drugs.patient_id = patients_with_appointments.patient_id) AND (patients_with_appointments.previous_appointment_date < prescription_drugs.device_created_at) AND (prescription_drugs.device_created_at < ((patients_with_appointments.month_date + '1 mon'::interval) + '15 days'::interval))) - ORDER BY 2, 3) visits ON ((patients_with_appointments.patient_id = visits.patient_id))) - ), patient_with_call_results AS ( - SELECT DISTINCT ON (patients_with_appointments_and_visits.patient_id, patients_with_appointments_and_visits.month_date) patients_with_appointments_and_visits.month_date, - patients_with_appointments_and_visits.patient_id, - patients_with_appointments_and_visits.hypertension, - patients_with_appointments_and_visits.diabetes, - patients_with_appointments_and_visits.htn_care_state, - patients_with_appointments_and_visits.month, - patients_with_appointments_and_visits.quarter, - patients_with_appointments_and_visits.year, - patients_with_appointments_and_visits.month_string, - patients_with_appointments_and_visits.quarter_string, - patients_with_appointments_and_visits.assigned_facility_id, - patients_with_appointments_and_visits.assigned_facility_slug, - patients_with_appointments_and_visits.assigned_facility_region_id, - patients_with_appointments_and_visits.assigned_block_slug, - patients_with_appointments_and_visits.assigned_block_region_id, - patients_with_appointments_and_visits.assigned_district_slug, - patients_with_appointments_and_visits.assigned_district_region_id, - patients_with_appointments_and_visits.assigned_state_slug, - patients_with_appointments_and_visits.assigned_state_region_id, - patients_with_appointments_and_visits.assigned_organization_slug, - patients_with_appointments_and_visits.assigned_organization_region_id, - patients_with_appointments_and_visits.previous_appointment_id, - patients_with_appointments_and_visits.previous_appointment_date, - patients_with_appointments_and_visits.previous_appointment_schedule_date, - patients_with_appointments_and_visits.visit_id, - patients_with_appointments_and_visits.visited_at_after_appointment, - ((previous_call_results.device_created_at AT TIME ZONE 'UTC'::text) AT TIME ZONE 'UTC'::text) AS previous_called_at, - previous_call_results.result_type AS previous_call_result_type, - previous_call_results.remove_reason AS previous_call_removed_from_overdue_list_reason, - ((next_call_results.device_created_at AT TIME ZONE 'UTC'::text) AT TIME ZONE 'UTC'::text) AS next_called_at, - next_call_results.result_type AS next_call_result_type, - next_call_results.remove_reason AS next_call_removed_from_overdue_list_reason, - next_call_results.user_id AS called_by_user_id - FROM ((patients_with_appointments_and_visits - LEFT JOIN public.call_results previous_call_results ON (((patients_with_appointments_and_visits.patient_id = previous_call_results.patient_id) AND (((previous_call_results.device_created_at AT TIME ZONE 'UTC'::text) AT TIME ZONE ( SELECT current_setting('TIMEZONE'::text) AS current_setting)) < patients_with_appointments_and_visits.month_date) AND (previous_call_results.device_created_at > patients_with_appointments_and_visits.previous_appointment_schedule_date)))) - LEFT JOIN public.call_results next_call_results ON (((patients_with_appointments_and_visits.patient_id = next_call_results.patient_id) AND (((next_call_results.device_created_at AT TIME ZONE 'UTC'::text) AT TIME ZONE ( SELECT current_setting('TIMEZONE'::text) AS current_setting)) >= patients_with_appointments_and_visits.month_date) AND (((next_call_results.device_created_at AT TIME ZONE 'UTC'::text) AT TIME ZONE ( SELECT current_setting('TIMEZONE'::text) AS current_setting)) < (patients_with_appointments_and_visits.month_date + '1 mon'::interval))))) - ORDER BY patients_with_appointments_and_visits.patient_id, patients_with_appointments_and_visits.month_date, next_call_results.device_created_at, previous_call_results.device_created_at DESC - ), patient_with_call_results_and_phone AS ( - SELECT DISTINCT ON (patient_with_call_results.patient_id, patient_with_call_results.month_date) patient_with_call_results.month_date, - patient_with_call_results.patient_id, - patient_with_call_results.hypertension, - patient_with_call_results.diabetes, - patient_with_call_results.htn_care_state, - patient_with_call_results.month, - patient_with_call_results.quarter, - patient_with_call_results.year, - patient_with_call_results.month_string, - patient_with_call_results.quarter_string, - patient_with_call_results.assigned_facility_id, - patient_with_call_results.assigned_facility_slug, - patient_with_call_results.assigned_facility_region_id, - patient_with_call_results.assigned_block_slug, - patient_with_call_results.assigned_block_region_id, - patient_with_call_results.assigned_district_slug, - patient_with_call_results.assigned_district_region_id, - patient_with_call_results.assigned_state_slug, - patient_with_call_results.assigned_state_region_id, - patient_with_call_results.assigned_organization_slug, - patient_with_call_results.assigned_organization_region_id, - patient_with_call_results.previous_appointment_id, - patient_with_call_results.previous_appointment_date, - patient_with_call_results.previous_appointment_schedule_date, - patient_with_call_results.visit_id, - patient_with_call_results.visited_at_after_appointment, - patient_with_call_results.previous_called_at, - patient_with_call_results.previous_call_result_type, - patient_with_call_results.previous_call_removed_from_overdue_list_reason, - patient_with_call_results.next_called_at, - patient_with_call_results.next_call_result_type, - patient_with_call_results.next_call_removed_from_overdue_list_reason, - patient_with_call_results.called_by_user_id, - patient_phone_numbers.number AS patient_phone_number - FROM (patient_with_call_results - LEFT JOIN public.patient_phone_numbers ON ((patient_phone_numbers.patient_id = patient_with_call_results.patient_id))) - ORDER BY patient_with_call_results.patient_id, patient_with_call_results.month_date - ) - SELECT patient_with_call_results_and_phone.month_date, - patient_with_call_results_and_phone.patient_id, - patient_with_call_results_and_phone.hypertension, - patient_with_call_results_and_phone.diabetes, - patient_with_call_results_and_phone.htn_care_state, - patient_with_call_results_and_phone.month, - patient_with_call_results_and_phone.quarter, - patient_with_call_results_and_phone.year, - patient_with_call_results_and_phone.month_string, - patient_with_call_results_and_phone.quarter_string, - patient_with_call_results_and_phone.assigned_facility_id, - patient_with_call_results_and_phone.assigned_facility_slug, - patient_with_call_results_and_phone.assigned_facility_region_id, - patient_with_call_results_and_phone.assigned_block_slug, - patient_with_call_results_and_phone.assigned_block_region_id, - patient_with_call_results_and_phone.assigned_district_slug, - patient_with_call_results_and_phone.assigned_district_region_id, - patient_with_call_results_and_phone.assigned_state_slug, - patient_with_call_results_and_phone.assigned_state_region_id, - patient_with_call_results_and_phone.assigned_organization_slug, - patient_with_call_results_and_phone.assigned_organization_region_id, - patient_with_call_results_and_phone.previous_appointment_id, - patient_with_call_results_and_phone.previous_appointment_date, - patient_with_call_results_and_phone.previous_appointment_schedule_date, - patient_with_call_results_and_phone.visited_at_after_appointment, - patient_with_call_results_and_phone.called_by_user_id, - patient_with_call_results_and_phone.next_called_at, - patient_with_call_results_and_phone.previous_called_at, - patient_with_call_results_and_phone.next_call_result_type, - patient_with_call_results_and_phone.next_call_removed_from_overdue_list_reason, - patient_with_call_results_and_phone.previous_call_result_type, - patient_with_call_results_and_phone.previous_call_removed_from_overdue_list_reason, - CASE - WHEN (patient_with_call_results_and_phone.previous_appointment_id IS NULL) THEN 'no'::text - WHEN (patient_with_call_results_and_phone.previous_appointment_schedule_date >= patient_with_call_results_and_phone.month_date) THEN 'no'::text - WHEN ((patient_with_call_results_and_phone.previous_appointment_schedule_date < patient_with_call_results_and_phone.month_date) AND (patient_with_call_results_and_phone.visited_at_after_appointment < patient_with_call_results_and_phone.month_date)) THEN 'no'::text - ELSE 'yes'::text - END AS is_overdue, - CASE - WHEN (patient_with_call_results_and_phone.next_called_at IS NULL) THEN 'no'::text - ELSE 'yes'::text - END AS has_called, - CASE - WHEN ((patient_with_call_results_and_phone.visited_at_after_appointment IS NULL) OR (patient_with_call_results_and_phone.next_called_at IS NULL)) THEN 'no'::text - WHEN (patient_with_call_results_and_phone.visited_at_after_appointment > (patient_with_call_results_and_phone.next_called_at + '15 days'::interval)) THEN 'no'::text - ELSE 'yes'::text - END AS has_visited_following_call, - CASE - WHEN (patient_with_call_results_and_phone.htn_care_state = 'lost_to_follow_up'::text) THEN 'yes'::text - ELSE 'no'::text - END AS ltfu, - CASE - WHEN (patient_with_call_results_and_phone.htn_care_state = 'under_care'::text) THEN 'yes'::text - ELSE 'no'::text - END AS under_care, - CASE - WHEN (patient_with_call_results_and_phone.patient_phone_number IS NULL) THEN 'no'::text - ELSE 'yes'::text - END AS has_phone, - CASE - WHEN ((patient_with_call_results_and_phone.previous_call_result_type)::text = 'removed_from_overdue_list'::text) THEN 'yes'::text - ELSE 'no'::text - END AS removed_from_overdue_list, - CASE - WHEN ((patient_with_call_results_and_phone.next_call_result_type)::text = 'removed_from_overdue_list'::text) THEN 'yes'::text - ELSE 'no'::text - END AS removed_from_overdue_list_during_the_month - FROM patient_with_call_results_and_phone - WITH NO DATA; - +CREATE VIEW public.reporting_overdue_patients AS SELECT * FROM simple_reporting.reporting_overdue_patients; -- -- Name: reporting_facility_states; Type: VIEW; Schema: public; Owner: - @@ -8879,21 +8651,6 @@ CREATE UNIQUE INDEX medicine_purposes_unique_name ON public.medicine_purposes US CREATE UNIQUE INDEX overdue_calls_month_date_patient_id ON public.reporting_overdue_calls USING btree (month_date, patient_id); - --- --- Name: overdue_patients_assigned_facility_region_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX overdue_patients_assigned_facility_region_id ON public.reporting_overdue_patients USING btree (assigned_facility_region_id); - - --- --- Name: overdue_patients_month_date_patient_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE UNIQUE INDEX overdue_patients_month_date_patient_id ON public.reporting_overdue_patients USING btree (month_date, patient_id); - - -- -- Name: patient_blood_pressures_patient_id_month_date; Type: INDEX; Schema: public; Owner: - -- @@ -9724,6 +9481,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20260422120000'), ('20260507063641'), ('20260513141718'), -('20260515103653'); +('20260515103653'), +('20260521101357'); diff --git a/db/views/reporting_overdue_patients_v01.sql b/db/views/reporting_overdue_patients_v01.sql deleted file mode 100644 index db22d4efc2..0000000000 --- a/db/views/reporting_overdue_patients_v01.sql +++ /dev/null @@ -1,229 +0,0 @@ -WITH patients_with_appointments AS ( - SELECT - DISTINCT ON (rps.patient_id, rps.month_date) - rps.month_date, - rps.patient_id, - rps.hypertension AS hypertension, - rps.diabetes AS diabetes, - rps.htn_care_state, - rps.month, - rps.quarter, - rps.year, - rps.month_string, - rps.quarter_string, - rps.assigned_facility_id, - rps.assigned_facility_slug, - rps.assigned_facility_region_id, - rps.assigned_block_slug, - rps.assigned_block_region_id, - rps.assigned_district_slug, - rps.assigned_district_region_id, - rps.assigned_state_slug, - rps.assigned_state_region_id, - rps.assigned_organization_slug, - rps.assigned_organization_region_id, - appointments.id AS previous_appointment_id, - appointments.device_created_at AS previous_appointment_date, - appointments.scheduled_date AS previous_appointment_schedule_date - FROM - reporting_patient_states rps - LEFT JOIN appointments ON appointments.patient_id = rps.patient_id - AND appointments.device_created_at < rps.month_date - WHERE - rps.status <> 'dead' - AND rps.month_date > NOW() - INTERVAL '24 months' - ORDER BY - rps.patient_id, - rps.month_date, - appointments.device_created_at DESC -), - -patients_with_appointments_and_visits AS ( - SELECT - patients_with_appointments.*, - visit_id, - visited_at_after_appointment - FROM - patients_with_appointments - LEFT JOIN lateral ( - SELECT - DISTINCT ON (patient_id) id AS visit_id, - patient_id, - recorded_at AS visited_at_after_appointment - FROM - blood_sugars - WHERE - deleted_at IS NULL - AND patient_id = patients_with_appointments.patient_id - AND patients_with_appointments.previous_appointment_date < blood_sugars.recorded_at - AND blood_sugars.recorded_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' - UNION ALL ( - SELECT - id AS visit_id, - patient_id, - recorded_at AS visited_at_after_appointment - FROM - blood_pressures - WHERE - deleted_at IS NULL - AND patient_id = patients_with_appointments.patient_id - AND patients_with_appointments.previous_appointment_date < blood_pressures.recorded_at - AND blood_pressures.recorded_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' - ) - UNION ALL ( - SELECT - id AS visit_id, - patient_id, - device_created_at AS visited_at_after_appointment - FROM - appointments AS patients_with_appointments_visit - WHERE - deleted_at IS NULL - AND patient_id = patients_with_appointments.patient_id - AND patients_with_appointments.previous_appointment_date < patients_with_appointments_visit.device_created_at - AND patients_with_appointments_visit.device_created_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' - ) - UNION ALL ( - SELECT - id AS visit_id, - patient_id, - device_created_at AS visited_at_after_appointment - FROM - prescription_drugs - WHERE - deleted_at IS NULL - AND patient_id = patients_with_appointments.patient_id - AND patients_with_appointments.previous_appointment_date < prescription_drugs.device_created_at - AND prescription_drugs.device_created_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' - ) - ORDER BY - patient_id, - visited_at_after_appointment - ) AS visits ON patients_with_appointments.patient_id = visits.patient_id -), - -patient_with_call_results AS ( - SELECT - DISTINCT ON ( - patients_with_appointments_and_visits.patient_id, - patients_with_appointments_and_visits.month_date - ) patients_with_appointments_and_visits.*, - previous_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE 'UTC' AS previous_called_at, - previous_call_results.result_type AS previous_call_result_type, - previous_call_results.remove_reason AS previous_call_removed_from_overdue_list_reason, - next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE 'UTC' AS next_called_at, - next_call_results.result_type AS next_call_result_type, - next_call_results.remove_reason as next_call_removed_from_overdue_list_reason, - next_call_results.user_id AS called_by_user_id - FROM - patients_with_appointments_and_visits - LEFT JOIN call_results previous_call_results ON patients_with_appointments_and_visits.patient_id = previous_call_results.patient_id - AND previous_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE ( - SELECT - current_setting('TIMEZONE') - ) < patients_with_appointments_and_visits.month_date - AND previous_call_results.device_created_at > previous_appointment_schedule_date - LEFT JOIN call_results next_call_results ON patients_with_appointments_and_visits.patient_id = next_call_results.patient_id - AND next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE ( - SELECT - current_setting('TIMEZONE') - ) >= patients_with_appointments_and_visits.month_date - AND next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE ( - SELECT - current_setting('TIMEZONE') - ) < patients_with_appointments_and_visits.month_date + INTERVAL '1 month' - ORDER BY - patients_with_appointments_and_visits.patient_id, - patients_with_appointments_and_visits.month_date, - next_call_results.device_created_at, - previous_call_results.device_created_at DESC -), - -patient_with_call_results_and_phone AS ( - SELECT - DISTINCT ON ( - patient_with_call_results.patient_id, - patient_with_call_results.month_date - ) patient_with_call_results.*, - patient_phone_numbers.number AS patient_phone_number - FROM - patient_with_call_results - LEFT JOIN patient_phone_numbers ON patient_phone_numbers.patient_id = patient_with_call_results.patient_id - ORDER BY - patient_with_call_results.patient_id, - patient_with_call_results.month_date -) - -SELECT - month_date, - patient_id, - hypertension, - diabetes, - htn_care_state, - month, - quarter, - year, - month_string, - quarter_string, - assigned_facility_id, - assigned_facility_slug, - assigned_facility_region_id, - assigned_block_slug, - assigned_block_region_id, - assigned_district_slug, - assigned_district_region_id, - assigned_state_slug, - assigned_state_region_id, - assigned_organization_slug, - assigned_organization_region_id, - previous_appointment_id, - previous_appointment_date, - previous_appointment_schedule_date, - visited_at_after_appointment, - called_by_user_id, - next_called_at, - previous_called_at, - next_call_result_type, - next_call_removed_from_overdue_list_reason, - previous_call_result_type, - previous_call_removed_from_overdue_list_reason, - CASE - WHEN (previous_appointment_schedule_date >= month_date) THEN 'no' - WHEN ( - previous_appointment_schedule_date < month_date - and visited_at_after_appointment < month_date - ) THEN 'no' - ELSE 'yes' - END AS is_overdue, - CASE - WHEN next_called_at IS NULL THEN 'no' - ELSE 'yes' - END AS has_called, - CASE - WHEN visited_at_after_appointment IS NULL - OR next_called_at IS NULL THEN 'no' - WHEN visited_at_after_appointment > next_called_at + INTERVAL '15 days' THEN 'no' - ELSE 'yes' - END AS has_visited_following_call, - CASE - WHEN htn_care_state = 'lost_to_follow_up' THEN 'yes' - ELSE 'no' - END AS ltfu, - CASE - WHEN htn_care_state = 'under_care' THEN 'yes' - ELSE 'no' - END AS under_care, - CASE - WHEN patient_phone_number IS NULL THEN 'no' - ELSE 'yes' - END AS has_phone, - CASE - WHEN previous_call_result_type = 'removed_from_overdue_list' THEN 'yes' - ELSE 'no' - END AS removed_from_overdue_list, - CASE - WHEN next_call_result_type = 'removed_from_overdue_list' THEN 'yes' - ELSE 'no' - END AS removed_from_overdue_list_during_the_month -FROM - patient_with_call_results_and_phone; diff --git a/db/views/reporting_overdue_patients_v02.sql b/db/views/reporting_overdue_patients_v02.sql deleted file mode 100644 index 6ba62ac8a6..0000000000 --- a/db/views/reporting_overdue_patients_v02.sql +++ /dev/null @@ -1,230 +0,0 @@ -WITH patients_with_appointments AS ( - SELECT - DISTINCT ON (rps.patient_id, rps.month_date) - rps.month_date, - rps.patient_id, - rps.hypertension AS hypertension, - rps.diabetes AS diabetes, - rps.htn_care_state, - rps.month, - rps.quarter, - rps.year, - rps.month_string, - rps.quarter_string, - rps.assigned_facility_id, - rps.assigned_facility_slug, - rps.assigned_facility_region_id, - rps.assigned_block_slug, - rps.assigned_block_region_id, - rps.assigned_district_slug, - rps.assigned_district_region_id, - rps.assigned_state_slug, - rps.assigned_state_region_id, - rps.assigned_organization_slug, - rps.assigned_organization_region_id, - appointments.id AS previous_appointment_id, - appointments.device_created_at AS previous_appointment_date, - appointments.scheduled_date AS previous_appointment_schedule_date - FROM - reporting_patient_states rps - LEFT JOIN appointments ON appointments.patient_id = rps.patient_id - AND appointments.device_created_at < rps.month_date - WHERE - rps.status <> 'dead' - AND rps.month_date > NOW() - INTERVAL '24 months' - ORDER BY - rps.patient_id, - rps.month_date, - appointments.device_created_at DESC -), - -patients_with_appointments_and_visits AS ( - SELECT - patients_with_appointments.*, - visit_id, - visited_at_after_appointment - FROM - patients_with_appointments - LEFT JOIN lateral ( - SELECT - DISTINCT ON (patient_id) id AS visit_id, - patient_id, - recorded_at AS visited_at_after_appointment - FROM - blood_sugars - WHERE - deleted_at IS NULL - AND patient_id = patients_with_appointments.patient_id - AND patients_with_appointments.previous_appointment_date < blood_sugars.recorded_at - AND blood_sugars.recorded_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' - UNION ALL ( - SELECT - id AS visit_id, - patient_id, - recorded_at AS visited_at_after_appointment - FROM - blood_pressures - WHERE - deleted_at IS NULL - AND patient_id = patients_with_appointments.patient_id - AND patients_with_appointments.previous_appointment_date < blood_pressures.recorded_at - AND blood_pressures.recorded_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' - ) - UNION ALL ( - SELECT - id AS visit_id, - patient_id, - device_created_at AS visited_at_after_appointment - FROM - appointments AS patients_with_appointments_visit - WHERE - deleted_at IS NULL - AND patient_id = patients_with_appointments.patient_id - AND patients_with_appointments.previous_appointment_date < patients_with_appointments_visit.device_created_at - AND patients_with_appointments_visit.device_created_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' - ) - UNION ALL ( - SELECT - id AS visit_id, - patient_id, - device_created_at AS visited_at_after_appointment - FROM - prescription_drugs - WHERE - deleted_at IS NULL - AND patient_id = patients_with_appointments.patient_id - AND patients_with_appointments.previous_appointment_date < prescription_drugs.device_created_at - AND prescription_drugs.device_created_at < patients_with_appointments.month_date + INTERVAL '1 month' + INTERVAL '15 days' - ) - ORDER BY - patient_id, - visited_at_after_appointment - ) AS visits ON patients_with_appointments.patient_id = visits.patient_id -), - -patient_with_call_results AS ( - SELECT - DISTINCT ON ( - patients_with_appointments_and_visits.patient_id, - patients_with_appointments_and_visits.month_date - ) patients_with_appointments_and_visits.*, - previous_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE 'UTC' AS previous_called_at, - previous_call_results.result_type AS previous_call_result_type, - previous_call_results.remove_reason AS previous_call_removed_from_overdue_list_reason, - next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE 'UTC' AS next_called_at, - next_call_results.result_type AS next_call_result_type, - next_call_results.remove_reason as next_call_removed_from_overdue_list_reason, - next_call_results.user_id AS called_by_user_id - FROM - patients_with_appointments_and_visits - LEFT JOIN call_results previous_call_results ON patients_with_appointments_and_visits.patient_id = previous_call_results.patient_id - AND previous_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE ( - SELECT - current_setting('TIMEZONE') - ) < patients_with_appointments_and_visits.month_date - AND previous_call_results.device_created_at > previous_appointment_schedule_date - LEFT JOIN call_results next_call_results ON patients_with_appointments_and_visits.patient_id = next_call_results.patient_id - AND next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE ( - SELECT - current_setting('TIMEZONE') - ) >= patients_with_appointments_and_visits.month_date - AND next_call_results.device_created_at AT TIME ZONE 'UTC' AT TIME ZONE ( - SELECT - current_setting('TIMEZONE') - ) < patients_with_appointments_and_visits.month_date + INTERVAL '1 month' - ORDER BY - patients_with_appointments_and_visits.patient_id, - patients_with_appointments_and_visits.month_date, - next_call_results.device_created_at, - previous_call_results.device_created_at DESC -), - -patient_with_call_results_and_phone AS ( - SELECT - DISTINCT ON ( - patient_with_call_results.patient_id, - patient_with_call_results.month_date - ) patient_with_call_results.*, - patient_phone_numbers.number AS patient_phone_number - FROM - patient_with_call_results - LEFT JOIN patient_phone_numbers ON patient_phone_numbers.patient_id = patient_with_call_results.patient_id - ORDER BY - patient_with_call_results.patient_id, - patient_with_call_results.month_date -) - -SELECT - month_date, - patient_id, - hypertension, - diabetes, - htn_care_state, - month, - quarter, - year, - month_string, - quarter_string, - assigned_facility_id, - assigned_facility_slug, - assigned_facility_region_id, - assigned_block_slug, - assigned_block_region_id, - assigned_district_slug, - assigned_district_region_id, - assigned_state_slug, - assigned_state_region_id, - assigned_organization_slug, - assigned_organization_region_id, - previous_appointment_id, - previous_appointment_date, - previous_appointment_schedule_date, - visited_at_after_appointment, - called_by_user_id, - next_called_at, - previous_called_at, - next_call_result_type, - next_call_removed_from_overdue_list_reason, - previous_call_result_type, - previous_call_removed_from_overdue_list_reason, - CASE - WHEN previous_appointment_id IS NULL THEN 'no' - WHEN (previous_appointment_schedule_date >= month_date) THEN 'no' - WHEN ( - previous_appointment_schedule_date < month_date - and visited_at_after_appointment < month_date - ) THEN 'no' - ELSE 'yes' - END AS is_overdue, - CASE - WHEN next_called_at IS NULL THEN 'no' - ELSE 'yes' - END AS has_called, - CASE - WHEN visited_at_after_appointment IS NULL - OR next_called_at IS NULL THEN 'no' - WHEN visited_at_after_appointment > next_called_at + INTERVAL '15 days' THEN 'no' - ELSE 'yes' - END AS has_visited_following_call, - CASE - WHEN htn_care_state = 'lost_to_follow_up' THEN 'yes' - ELSE 'no' - END AS ltfu, - CASE - WHEN htn_care_state = 'under_care' THEN 'yes' - ELSE 'no' - END AS under_care, - CASE - WHEN patient_phone_number IS NULL THEN 'no' - ELSE 'yes' - END AS has_phone, - CASE - WHEN previous_call_result_type = 'removed_from_overdue_list' THEN 'yes' - ELSE 'no' - END AS removed_from_overdue_list, - CASE - WHEN next_call_result_type = 'removed_from_overdue_list' THEN 'yes' - ELSE 'no' - END AS removed_from_overdue_list_during_the_month -FROM - patient_with_call_results_and_phone; diff --git a/spec/models/reports/overdue_patient_spec.rb b/spec/models/reports/overdue_patient_spec.rb index 7c4dfee044..7a07ed99be 100644 --- a/spec/models/reports/overdue_patient_spec.rb +++ b/spec/models/reports/overdue_patient_spec.rb @@ -22,6 +22,7 @@ create(:patient) dead_patient = create(:patient, status: "dead") Reports::PatientState.partitioned_refresh(Date.today) + Reports::OverduePatient.partitioned_refresh(Date.today) described_class.refresh with_reporting_time_zone do @@ -425,4 +426,10 @@ expect(described_class.partitioned?).to be(true) end end + + describe "#materialized?" do + it "returns false" do + expect(described_class.materialized?).to be(false) + end + end end diff --git a/spec/models/reports/region_summary_schema_spec.rb b/spec/models/reports/region_summary_schema_spec.rb index ac3a086e1d..79f7aa4232 100644 --- a/spec/models/reports/region_summary_schema_spec.rb +++ b/spec/models/reports/region_summary_schema_spec.rb @@ -1231,6 +1231,7 @@ def refresh_views before { allow(Reports::PatientState).to receive(:get_refresh_months).and_return(ReportingHelpers.get_refresh_months_between_dates(Date.today - 3.months, Date.today)) allow(Reports::FacilityState).to receive(:get_refresh_months).and_return(ReportingHelpers.get_refresh_months_between_dates(Date.today - 3.months, Date.today)) + allow(Reports::OverduePatient).to receive(:get_refresh_months).and_return(ReportingHelpers.get_refresh_months_between_dates(Date.today - 3.months, Date.today)) } describe "#patients_called_rates" do diff --git a/spec/models/reports/region_summary_spec.rb b/spec/models/reports/region_summary_spec.rb index 27ced30fcc..fda3a69ed7 100644 --- a/spec/models/reports/region_summary_spec.rb +++ b/spec/models/reports/region_summary_spec.rb @@ -771,6 +771,7 @@ before { allow(Reports::PatientState).to receive(:get_refresh_months).and_return(ReportingHelpers.get_refresh_months_between_dates(jan_2019.to_date, Date.today)) allow(Reports::FacilityState).to receive(:get_refresh_months).and_return(ReportingHelpers.get_refresh_months_between_dates(jan_2019.to_date, Date.today)) + allow(Reports::OverduePatient).to receive(:get_refresh_months).and_return(ReportingHelpers.get_refresh_months_between_dates(jan_2019.to_date, Date.today)) } it "return the count of overdue patients" do diff --git a/spec/models/reports/repository_spec.rb b/spec/models/reports/repository_spec.rb index e77e484bf9..6e67d90f44 100644 --- a/spec/models/reports/repository_spec.rb +++ b/spec/models/reports/repository_spec.rb @@ -188,6 +188,7 @@ create(:call_result, user: user_1, facility: facility, patient: patient_3, device_created_at: one_month_ago) create(:call_result, user: user_2, facility: facility, patient: patient_4, device_created_at: two_months_ago) allow(Reports::PatientState).to receive(:get_refresh_months).and_return(ReportingHelpers.get_refresh_months_between_dates(10.months.ago.to_date, Date.today)) + allow(Reports::OverduePatient).to receive(:get_refresh_months).and_return(ReportingHelpers.get_refresh_months_between_dates(10.months.ago.to_date, Date.today)) refresh_views repo = Reports::Repository.new(facility.region, periods: (two_months_ago.to_period..this_month.to_period))