, * patients_by_unit: array>, * duty_by_unit: array>, * placement_by_unit: array, * selected_unit: ?CareUnit, * } */ public function board( Organization $organization, Member $member, string $ownerRef, ?int $unitId = null, ): array { $dutyToday = RosterEntry::owned($ownerRef) ->where('organization_id', $organization->id) ->where('member_id', $member->id) ->whereDate('duty_date', now()->toDateString()) ->where('status', '!=', RosterEntry::STATUS_CANCELLED) ->with(['shift', 'careUnit.department.branch']) ->orderBy('shift_id') ->get(); $placements = StaffAssignment::owned($ownerRef) ->where('organization_id', $organization->id) ->where('member_id', $member->id) ->where('status', 'active') ->unitPlacements() ->effectiveOn(now()) ->whereNotNull('care_unit_id') ->with(['careUnit.department.branch']) ->get(); $unitIds = $dutyToday->pluck('care_unit_id') ->merge($placements->pluck('care_unit_id')) ->filter() ->map(fn ($id) => (int) $id) ->unique() ->values(); $units = CareUnit::owned($ownerRef) ->where('organization_id', $organization->id) ->whereIn('id', $unitIds->all() ?: [0]) ->where('is_active', true) ->with('department.branch') ->orderBy('name') ->get() ->keyBy('id'); // Preserve duty-first ordering, then remaining placements. $ordered = collect(); foreach ($dutyToday as $entry) { $id = (int) $entry->care_unit_id; if ($units->has($id) && ! $ordered->has($id)) { $ordered->put($id, $units->get($id)); } } foreach ($placements as $assignment) { $id = (int) $assignment->care_unit_id; if ($units->has($id) && ! $ordered->has($id)) { $ordered->put($id, $units->get($id)); } } $selected = null; if ($unitId && $ordered->has($unitId)) { $selected = $ordered->get($unitId); } elseif ($ordered->isNotEmpty()) { $selected = $ordered->first(); } $patientsByUnit = []; foreach ($ordered as $id => $unit) { $patientsByUnit[$id] = Visit::owned($ownerRef) ->where('organization_id', $organization->id) ->where('care_unit_id', $id) ->whereIn('status', [Visit::STATUS_OPEN, Visit::STATUS_IN_PROGRESS]) ->with(['patient', 'bed']) ->orderBy('placed_at') ->get(); } $dutyByUnit = []; foreach ($dutyToday as $entry) { $id = (int) $entry->care_unit_id; $dutyByUnit[$id] ??= collect(); $dutyByUnit[$id]->push($entry); } $placementByUnit = []; foreach ($placements as $assignment) { $placementByUnit[(int) $assignment->care_unit_id] = $assignment; } return [ 'units' => $ordered->values(), 'patients_by_unit' => $patientsByUnit, 'duty_by_unit' => $dutyByUnit, 'placement_by_unit' => $placementByUnit, 'selected_unit' => $selected, ]; } }