Fix Call next by advancing Care waiters and reclaiming desk tickets.
Deploy Ladill Care / deploy (push) Successful in 51s

Call next now picks the next board appointment, issues or reclaims its ticket onto the calling desk, and still fires display/voice announcements — so patients are not left stuck when tickets sit on the wrong point after sync-on-GET was removed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-18 20:18:52 +00:00
co-authored by Cursor
parent eaba400c7c
commit c123097f3c
3 changed files with 397 additions and 17 deletions
+119
View File
@@ -505,4 +505,123 @@ class CareQueueBridgeTest extends TestCase
->assertSee('Call again');
Http::assertNothingSent();
}
public function test_call_next_reclaims_ticket_from_wrong_desk_and_announces(): void
{
Http::fake();
$doctor = \App\Models\Practitioner::create([
'owner_ref' => $this->owner->public_id,
'organization_id' => $this->organization->id,
'branch_id' => $this->branch->id,
'name' => 'Dr. Reclaim',
'room' => 'Room 7',
'is_active' => true,
]);
$other = \App\Models\Practitioner::create([
'owner_ref' => $this->owner->public_id,
'organization_id' => $this->organization->id,
'branch_id' => $this->branch->id,
'name' => 'Dr. Other',
'room' => 'Room 8',
'is_active' => true,
]);
app(\App\Services\Care\CareQueueProvisioner::class)->ensure(
$this->organization->fresh(),
CareQueueContexts::CONSULTATION,
$this->branch->id,
);
$queue = \App\Models\CareServiceQueue::query()
->where('organization_id', $this->organization->id)
->where('context', CareQueueContexts::CONSULTATION)
->where('branch_id', $this->branch->id)
->firstOrFail();
$doctorPoint = \App\Models\CareServicePoint::query()
->where('service_queue_id', $queue->id)
->where('kind', 'practitioner')
->where('ref_id', $doctor->id)
->firstOrFail();
$otherPoint = \App\Models\CareServicePoint::query()
->where('service_queue_id', $queue->id)
->where('kind', 'practitioner')
->where('ref_id', $other->id)
->firstOrFail();
$ticketUuid = (string) \Illuminate\Support\Str::uuid();
CareQueueTicket::create([
'uuid' => $ticketUuid,
'owner_ref' => $this->owner->public_id,
'organization_id' => $this->organization->id,
'service_queue_id' => $queue->id,
'service_point_id' => $otherPoint->id,
'ticket_number' => 'C099',
'status' => CareQueueTicket::STATUS_WAITING,
'priority' => 'walk_in',
'customer_name' => 'Ada Lovelace',
'care_entity' => 'appointment',
'care_entity_id' => null,
]);
$appointment = Appointment::create([
'owner_ref' => $this->owner->public_id,
'organization_id' => $this->organization->id,
'branch_id' => $this->branch->id,
'patient_id' => $this->patient->id,
'practitioner_id' => $doctor->id,
'type' => Appointment::TYPE_WALK_IN,
'status' => Appointment::STATUS_WAITING,
'scheduled_at' => now(),
'waiting_at' => now(),
'queue_position' => 1,
'queue_ticket_uuid' => $ticketUuid,
'queue_ticket_number' => 'C099',
'queue_ticket_status' => 'waiting',
]);
CareQueueTicket::where('uuid', $ticketUuid)->update([
'care_entity_id' => $appointment->id,
'care_entity_uuid' => $appointment->uuid,
]);
$this->actingAs($this->owner)
->from(route('care.queue.index'))
->post(route('care.queue.call-next'), [
'branch_id' => $this->branch->id,
'practitioner_id' => $doctor->id,
])
->assertSessionHas('success')
->assertRedirect(route('care.appointments.show', $appointment));
$appointment = $appointment->fresh();
$this->assertSame('called', $appointment->queue_ticket_status);
$this->assertSame($doctorPoint->uuid, $appointment->queue_service_point_uuid);
$this->assertDatabaseHas('care_queue_tickets', [
'uuid' => $ticketUuid,
'status' => CareQueueTicket::STATUS_CALLED,
'service_point_id' => $doctorPoint->id,
]);
$this->assertDatabaseHas('care_voice_announcements', [
'organization_id' => $this->organization->id,
'branch_id' => $this->branch->id,
'status' => 'pending',
]);
$this->actingAs($this->owner)
->get(route('care.queue.index', [
'branch_id' => $this->branch->id,
'practitioner_id' => $doctor->id,
]))
->assertOk()
->assertSee('Called')
->assertSee('C099');
Http::assertNothingSent();
}
}