*/ public const CLINIC_KINDS = ['outpatient', 'service']; public function isClinicUnit(CareUnit $unit): bool { return in_array($unit->kind, self::CLINIC_KINDS, true); } /** * Active visits nurses should see for this unit. * * @return Collection */ public function visitsForUnit(CareUnit $unit, string $ownerRef): Collection { $unit->loadMissing('department'); return $this->queryForUnit($unit, $ownerRef) ->with(['patient', 'bed', 'appointment']) ->orderByRaw('care_unit_id is null') // placed first ->orderBy('placed_at') ->orderBy('checked_in_at') ->get(); } public function visitBelongsToUnit(Visit $visit, CareUnit $unit): bool { if ((int) $visit->organization_id !== (int) $unit->organization_id) { return false; } if (! in_array($visit->status, [Visit::STATUS_OPEN, Visit::STATUS_IN_PROGRESS], true)) { return false; } if ((int) $visit->care_unit_id === (int) $unit->id) { return true; } if (! $this->isClinicUnit($unit) || $visit->care_unit_id !== null) { return false; } $unit->loadMissing('department'); $branchId = $unit->department?->branch_id; if (! $branchId || (int) $visit->branch_id !== (int) $branchId) { return false; } $departmentId = $unit->department_id; if (! $departmentId) { return false; } $appointment = $visit->relationLoaded('appointment') ? $visit->appointment : $visit->appointment()->first(); return $appointment !== null && (int) $appointment->department_id === (int) $departmentId; } /** * Soft-place an eligible clinic visit onto the unit when a nurse acts on it. */ public function ensurePlaced( Visit $visit, CareUnit $unit, string $ownerRef, ?string $actorRef = null, ): Visit { $visit->refresh(); if ((int) $visit->care_unit_id === (int) $unit->id) { return $visit; } if (! $this->visitBelongsToUnit($visit, $unit)) { abort(404); } if ($visit->care_unit_id !== null) { abort(404); } app(VisitPlacementService::class)->place( $visit, $unit, null, $ownerRef, $actorRef, 'Auto-placed from outpatient nursing board', ); return $visit->fresh(['patient', 'bed', 'careUnit', 'appointment']); } /** * @return Builder */ protected function queryForUnit(CareUnit $unit, string $ownerRef): Builder { $query = Visit::owned($ownerRef) ->where('organization_id', $unit->organization_id) ->whereIn('status', [Visit::STATUS_OPEN, Visit::STATUS_IN_PROGRESS]); if (! $this->isClinicUnit($unit)) { return $query->where('care_unit_id', $unit->id); } $unit->loadMissing('department'); $branchId = $unit->department?->branch_id; $departmentId = $unit->department_id; return $query->where(function (Builder $q) use ($unit, $branchId, $departmentId) { $q->where('care_unit_id', $unit->id); if ($branchId && $departmentId) { $q->orWhere(function (Builder $clinic) use ($branchId, $departmentId) { $clinic->whereNull('care_unit_id') ->where('branch_id', $branchId) ->whereHas('appointment', fn (Builder $a) => $a->where('department_id', $departmentId)); }); } }); } }