diff --git a/resources/views/care/partials/queue-board-card.blade.php b/resources/views/care/partials/queue-board-card.blade.php index 6000033..0cfe04a 100644 --- a/resources/views/care/partials/queue-board-card.blade.php +++ b/resources/views/care/partials/queue-board-card.blade.php @@ -3,20 +3,34 @@ Expected: $appointment, $stage (waiting|called|in_care|done), $canConsult, $queueIntegration, $startRouteName, $openInCareUrl (callable) + + Open (view workspace / form) is available whenever a destination URL exists — + not gated by canConsult. Start / Call again remain consult-manage only. --}} @php $stage = $stage ?? 'waiting'; $ticketStatus = $appointment->queue_ticket_status ?? null; $isCalled = in_array($ticketStatus, ['called', 'serving'], true); $openUrl = isset($openInCareUrl) ? $openInCareUrl($appointment) : null; + $canConsult = $canConsult ?? false; @endphp -
$stage === 'called' || ($stage === 'waiting' && $isCalled), - 'border-emerald-200 bg-emerald-50/60' => $stage === 'in_care', - 'border-slate-100 bg-slate-50/80' => $stage === 'waiting' && ! $isCalled, - 'border-slate-100 bg-white opacity-90' => $stage === 'done', -])> +
(bool) $openUrl, + 'border-indigo-200 bg-indigo-50/70 ring-1 ring-indigo-100' => $stage === 'called' || ($stage === 'waiting' && $isCalled), + 'border-emerald-200 bg-emerald-50/60' => $stage === 'in_care', + 'border-slate-100 bg-slate-50/80' => $stage === 'waiting' && ! $isCalled, + 'border-slate-100 bg-white opacity-90' => $stage === 'done', + ]) +>
@if (! empty($queueIntegration['enabled']) && $appointment->queue_ticket_number) @include('care.partials.queue-ticket', [ @@ -51,7 +65,7 @@
-
+
@if ($stage === 'waiting' || $stage === 'called') @if (! empty($queueIntegration['enabled']) && $appointment->queue_ticket_uuid && $isCalled && $canConsult)
@@ -71,6 +85,13 @@
@endif + @if ($openUrl) + ! $canConsult, + 'border border-slate-200 bg-white text-slate-700 hover:bg-slate-50' => $canConsult, + ])>Open + @endif @elseif ($stage === 'in_care') @if (! empty($queueIntegration['enabled']) && $appointment->queue_ticket_uuid && $isCalled && $canConsult)
@@ -81,6 +102,8 @@ @if ($openUrl) Open @endif + @elseif ($stage === 'done' && $openUrl) + Open @endif
diff --git a/resources/views/care/partials/queue-board.blade.php b/resources/views/care/partials/queue-board.blade.php index 8a9920b..376ccbc 100644 --- a/resources/views/care/partials/queue-board.blade.php +++ b/resources/views/care/partials/queue-board.blade.php @@ -8,7 +8,8 @@ - $canConsult (bool) - $queueCallNextRoute, $queueCallNextParams (optional — if set, Call next renders above board) - $startRouteName (default care.queue.start) — route(name, $appointment) - - $openInCareUrl (callable Appointment $a): ?string — link for in-care Open + - $openInCareUrl (callable Appointment $a): ?string — workspace/form URL for Open + (waiting / called / in-care / done; not gated by canConsult) - $inCareLabel (default "In care") - $lockToPractitioner, $canSwitchBranch, $branches, $practitioners, $practitionerId (filter bar) - $showFilters (default true) diff --git a/tests/Feature/CarePatientQueueAccessTest.php b/tests/Feature/CarePatientQueueAccessTest.php index 330b252..492822c 100644 --- a/tests/Feature/CarePatientQueueAccessTest.php +++ b/tests/Feature/CarePatientQueueAccessTest.php @@ -212,20 +212,107 @@ class CarePatientQueueAccessTest extends TestCase 'checked_in_at' => now(), ]); - $this->actingAs($nurseUser) + $workspaceUrl = route('care.specialty.workspace', [ + 'module' => 'blood_bank', + 'visit' => $visit, + ], absolute: false); + + $listHtml = $this->actingAs($nurseUser) ->get(route('care.specialty.show', 'blood_bank')) ->assertOk() ->assertSee('Blood Bank') ->assertSee('Patient flow') ->assertSee('Waiting') ->assertSee('Kwame Donor') - ->assertDontSee('No open visit selected'); + ->assertSee('Open') + ->assertDontSee('No open visit selected') + ->getContent(); + + $this->assertStringContainsString($workspaceUrl, $listHtml); + $this->assertStringNotContainsString('>Start', $listHtml); + + $this->actingAs($nurseUser) + ->get(route('care.specialty.workspace', ['module' => 'blood_bank', 'visit' => $visit])) + ->assertOk(); $this->actingAs($nurseUser) ->get(route('care.specialty.workspace', 'blood_bank')) ->assertRedirect(route('care.specialty.show', 'blood_bank')); } + public function test_nurse_can_open_emergency_visit_from_specialty_list(): void + { + [$nurseUser] = $this->makeStaff('nurse', 'nurse-er-open'); + + $modules = app(SpecialtyModuleService::class); + $modules->ensureDefaultModulesProvisioned($this->organization, $this->owner->public_id); + $modules->activate($this->organization->fresh(), $this->owner->public_id, 'emergency'); + + $department = Department::query() + ->where('branch_id', $this->branch->id) + ->where('type', 'emergency') + ->firstOrFail(); + + $patient = Patient::create([ + 'owner_ref' => $this->owner->public_id, + 'organization_id' => $this->organization->id, + 'branch_id' => $this->branch->id, + 'patient_number' => 'P-ER-OPEN', + 'first_name' => 'Akosua', + 'last_name' => 'Owusu', + 'gender' => 'female', + 'date_of_birth' => '1990-03-15', + ]); + + $visit = Visit::create([ + 'owner_ref' => $this->owner->public_id, + 'organization_id' => $this->organization->id, + 'branch_id' => $this->branch->id, + 'patient_id' => $patient->id, + 'status' => Visit::STATUS_OPEN, + 'checked_in_at' => now(), + 'specialty_stage' => 'arrival', + ]); + + Appointment::create([ + 'owner_ref' => $this->owner->public_id, + 'organization_id' => $this->organization->id, + 'branch_id' => $this->branch->id, + 'patient_id' => $patient->id, + 'department_id' => $department->id, + 'visit_id' => $visit->id, + 'type' => Appointment::TYPE_WALK_IN, + 'status' => Appointment::STATUS_WAITING, + 'scheduled_at' => now(), + 'waiting_at' => now(), + 'checked_in_at' => now(), + 'queue_ticket_number' => 'ER002', + 'queue_ticket_status' => 'waiting', + ]); + + $workspaceUrl = route('care.specialty.workspace', [ + 'module' => 'emergency', + 'visit' => $visit, + ], absolute: false); + + $html = $this->actingAs($nurseUser) + ->get(route('care.specialty.show', 'emergency')) + ->assertOk() + ->assertSee('Akosua Owusu') + ->assertSee('ER002') + ->assertSee('Open') + ->assertDontSee('>Start', false) + ->getContent(); + + $this->assertStringContainsString($workspaceUrl, $html); + + $this->actingAs($nurseUser) + ->get(route('care.specialty.workspace', ['module' => 'emergency', 'visit' => $visit])) + ->assertOk() + ->assertSee('Akosua Owusu') + ->assertDontSee('No open visit selected'); + } + public function test_nurse_specialty_show_redirects_to_workspace_not_queue(): void { [$nurseUser] = $this->makeStaff('nurse', 'nurse-spec-er');