@@ -229,6 +229,7 @@ async def patientsTotal(
229229 async def recent_patients (
230230 self ,
231231 info : Info ,
232+ root_location_ids : list [strawberry .ID ] | None = None ,
232233 filtering : list [FilterInput ] | None = None ,
233234 sorting : list [SortInput ] | None = None ,
234235 pagination : PaginationInput | None = None ,
@@ -270,12 +271,52 @@ async def recent_patients(
270271 info .context .user , query , accessible_location_ids
271272 )
272273
274+ if root_location_ids :
275+ valid_root_ids = [lid for lid in root_location_ids if lid in accessible_location_ids ]
276+ if valid_root_ids :
277+ root_cte = (
278+ select (models .LocationNode .id )
279+ .where (models .LocationNode .id .in_ (valid_root_ids ))
280+ .cte (name = "recent_root_descendants" , recursive = True )
281+ )
282+ root_children = select (models .LocationNode .id ).join (
283+ root_cte , models .LocationNode .parent_id == root_cte .c .id
284+ )
285+ root_cte = root_cte .union_all (root_children )
286+ patient_locations_root = aliased (models .patient_locations )
287+ patient_teams_root = aliased (models .patient_teams )
288+ query = (
289+ query .outerjoin (
290+ patient_locations_root ,
291+ models .Patient .id == patient_locations_root .c .patient_id ,
292+ )
293+ .outerjoin (
294+ patient_teams_root ,
295+ models .Patient .id == patient_teams_root .c .patient_id ,
296+ )
297+ .where (
298+ (models .Patient .clinic_id .in_ (select (root_cte .c .id )))
299+ | (
300+ models .Patient .position_id .isnot (None )
301+ & models .Patient .position_id .in_ (select (root_cte .c .id ))
302+ )
303+ | (
304+ models .Patient .assigned_location_id .isnot (None )
305+ & models .Patient .assigned_location_id .in_ (select (root_cte .c .id ))
306+ )
307+ | (patient_locations_root .c .location_id .in_ (select (root_cte .c .id )))
308+ | (patient_teams_root .c .location_id .in_ (select (root_cte .c .id )))
309+ )
310+ .distinct ()
311+ )
312+
273313 return query
274314
275315 @strawberry .field
276316 async def recentPatientsTotal (
277317 self ,
278318 info : Info ,
319+ root_location_ids : list [strawberry .ID ] | None = None ,
279320 filtering : list [FilterInput ] | None = None ,
280321 sorting : list [SortInput ] | None = None ,
281322 search : FullTextSearchInput | None = None ,
@@ -311,6 +352,45 @@ async def recentPatientsTotal(
311352 info .context .user , query , accessible_location_ids
312353 )
313354
355+ if root_location_ids :
356+ valid_root_ids = [lid for lid in root_location_ids if lid in accessible_location_ids ]
357+ if valid_root_ids :
358+ root_cte = (
359+ select (models .LocationNode .id )
360+ .where (models .LocationNode .id .in_ (valid_root_ids ))
361+ .cte (name = "recent_patients_total_root" , recursive = True )
362+ )
363+ root_children = select (models .LocationNode .id ).join (
364+ root_cte , models .LocationNode .parent_id == root_cte .c .id
365+ )
366+ root_cte = root_cte .union_all (root_children )
367+ patient_locations_root = aliased (models .patient_locations )
368+ patient_teams_root = aliased (models .patient_teams )
369+ query = (
370+ query .outerjoin (
371+ patient_locations_root ,
372+ models .Patient .id == patient_locations_root .c .patient_id ,
373+ )
374+ .outerjoin (
375+ patient_teams_root ,
376+ models .Patient .id == patient_teams_root .c .patient_id ,
377+ )
378+ .where (
379+ (models .Patient .clinic_id .in_ (select (root_cte .c .id )))
380+ | (
381+ models .Patient .position_id .isnot (None )
382+ & models .Patient .position_id .in_ (select (root_cte .c .id ))
383+ )
384+ | (
385+ models .Patient .assigned_location_id .isnot (None )
386+ & models .Patient .assigned_location_id .in_ (select (root_cte .c .id ))
387+ )
388+ | (patient_locations_root .c .location_id .in_ (select (root_cte .c .id )))
389+ | (patient_teams_root .c .location_id .in_ (select (root_cte .c .id )))
390+ )
391+ .distinct ()
392+ )
393+
314394 if search and search is not strawberry .UNSET :
315395 query = apply_full_text_search (query , search , models .Patient )
316396
0 commit comments