|
| 1 | + |
| 2 | +# Active Patient Report with Patient Tags |
| 3 | + |
| 4 | +> Currently active patients at Arike with zone / place-of-care tags with the most relevant encounter or upcoming appointment date |
| 5 | +
|
| 6 | +## Purpose |
| 7 | + |
| 8 | +Identifies the set of **currently active patients** at Arike and their zone and place-of-care , plus a single `date` column that reflects either their most recent encounter (within the last 100 days) or their earliest upcoming appointment (within the next 100 days). |
| 9 | + |
| 10 | +An "active patient" is defined as one who: |
| 11 | + |
| 12 | +- is **not deceased**, and |
| 13 | +- does **not** carry the exclusion tag (`tag_id = 70`), and |
| 14 | +- either has an encounter at facility 2 in the last 100 days, **or** has an upcoming booked / checked-in / in-consultation appointment at facility 2 in the next 100 days. |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | +## Parameters |
| 19 | + |
| 20 | +| Parameter | Type | Description | Example | |
| 21 | +|-----------|------|-------------|---------| |
| 22 | +| `zone_filter` | TEXT | Filter by resolved zone tag display (exact match) | `'Zone A'` | |
| 23 | +| `place_of_care` | TEXT | Filter by resolved place-of-care tag display (exact match) | `'Home'` | |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## Query |
| 28 | + |
| 29 | +```sql |
| 30 | +WITH active_patients AS ( |
| 31 | + SELECT DISTINCT |
| 32 | + ep.id AS patient_id, |
| 33 | + ep.name AS patient_name, |
| 34 | + ep.gender, |
| 35 | + ep.phone_number, |
| 36 | + pi.value AS adm, |
| 37 | + ep.instance_tags |
| 38 | + FROM emr_patient ep |
| 39 | + LEFT JOIN emr_patientidentifier pi |
| 40 | + ON ep.id = pi.patient_id |
| 41 | + AND pi.config_id = 2 |
| 42 | + WHERE ep.deceased_datetime IS NULL |
| 43 | + AND NOT (70 = ANY(ep.instance_tags)) |
| 44 | + AND ( |
| 45 | + EXISTS ( |
| 46 | + SELECT 1 |
| 47 | + FROM emr_encounter ee |
| 48 | + WHERE ee.patient_id = ep.id |
| 49 | + AND ee.created_date >= CURRENT_DATE - INTERVAL '100 days' |
| 50 | + AND ee.facility_id = 2 |
| 51 | + AND ee.deleted = FALSE |
| 52 | + ) |
| 53 | + OR |
| 54 | + EXISTS ( |
| 55 | + SELECT 1 |
| 56 | + FROM emr_tokenbooking tb |
| 57 | + JOIN emr_tokenslot ts |
| 58 | + ON tb.token_slot_id = ts.id |
| 59 | + JOIN emr_schedulableresource sbr |
| 60 | + ON ts.resource_id = sbr.id |
| 61 | + WHERE tb.patient_id = ep.id |
| 62 | + AND ts.start_datetime >= CURRENT_DATE |
| 63 | + AND ts.start_datetime < CURRENT_DATE + INTERVAL '100 days' |
| 64 | + AND sbr.facility_id = 2 |
| 65 | + AND tb.deleted = FALSE |
| 66 | + AND ts.deleted = FALSE |
| 67 | + AND tb.status IN ('booked', 'checked_in', 'in_consultation') |
| 68 | + ) |
| 69 | + ) |
| 70 | +), |
| 71 | +patient_tags AS ( |
| 72 | + SELECT |
| 73 | + ap.patient_id, |
| 74 | + COALESCE(MAX(CASE WHEN et.parent_id = 55 THEN et.display END), 'unassigned') AS zone, |
| 75 | + COALESCE(MAX(CASE WHEN et.parent_id = 71 THEN et.display END), 'unassigned') AS place_of_care |
| 76 | + FROM active_patients ap |
| 77 | + LEFT JOIN LATERAL unnest(ap.instance_tags) AS tag_id ON TRUE |
| 78 | + LEFT JOIN emr_tagconfig et |
| 79 | + ON et.id = tag_id |
| 80 | + AND et.deleted = FALSE |
| 81 | + GROUP BY ap.patient_id |
| 82 | +) |
| 83 | +SELECT |
| 84 | + ap.patient_name, |
| 85 | + ap.phone_number, |
| 86 | + ap.adm, |
| 87 | + ap.gender, |
| 88 | + pt.zone, |
| 89 | + pt.place_of_care, |
| 90 | + COALESCE( |
| 91 | + (SELECT MAX(ee.created_date) |
| 92 | + FROM emr_encounter ee |
| 93 | + WHERE ee.patient_id = ap.patient_id |
| 94 | + AND ee.created_date >= CURRENT_DATE - INTERVAL '100 days' |
| 95 | + AND ee.facility_id = 2), |
| 96 | + (SELECT MIN(ts.start_datetime) |
| 97 | + FROM emr_tokenbooking tb |
| 98 | + JOIN emr_tokenslot ts |
| 99 | + ON tb.token_slot_id = ts.id |
| 100 | + JOIN emr_schedulableresource sbr |
| 101 | + ON ts.resource_id = sbr.id |
| 102 | + WHERE tb.patient_id = ap.patient_id |
| 103 | + AND ts.start_datetime >= CURRENT_DATE |
| 104 | + AND ts.start_datetime < CURRENT_DATE + INTERVAL '100 days' |
| 105 | + AND sbr.facility_id = 2 |
| 106 | + AND tb.deleted = FALSE |
| 107 | + AND ts.deleted = FALSE |
| 108 | + AND tb.status IN ('booked', 'checked_in', 'in_consultation')) |
| 109 | + ) AS date |
| 110 | +FROM active_patients ap |
| 111 | +LEFT JOIN patient_tags pt |
| 112 | + ON pt.patient_id = ap.patient_id |
| 113 | +WHERE 1=1 |
| 114 | + --[[AND pt.zone = {{zone_filter}}]] |
| 115 | + --[[AND pt.place_of_care = {{place_of_care}}]] |
| 116 | +ORDER BY ap.patient_name; |
| 117 | +``` |
| 118 | + |
| 119 | +## Notes |
| 120 | + |
| 121 | +- **Active-patient definition:** Encoded in the `active_patients` CTE — not deceased, not carrying tag `70`, and either has a recent encounter (last 100 days) **or** an upcoming appointment (next 100 days) at `facility_id = 2` (Arike). |
| 122 | +- **Hardcoded IDs:** |
| 123 | + - `facility_id = 2` — Arike facility. |
| 124 | + - `pi.config_id = 2` — ADM patient identifier configuration. |
| 125 | + - `70` — exclusion instance tag (patients carrying this tag are omitted). |
| 126 | + - `parent_id = 55` — parent tag for **zone**. |
| 127 | + - `parent_id = 71` — parent tag for **place of care**. |
| 128 | + Update any of these if the underlying configuration changes. |
| 129 | +- **Metabase filters:** |
| 130 | + - `[[AND pt.zone = {{zone_filter}}]]` and `[[AND pt.place_of_care = {{place_of_care}}]]` — exact-match filters applied on the resolved tag columns. |
| 131 | +- Results are ordered alphabetically by patient name. |
| 132 | + |
| 133 | +*Last updated: 2026-07-07* |
0 commit comments