Files
ladill-care/app/Services/Care/CareVoiceAnnouncementService.php
T
isaaccladandCursor 03befd1e7f
Deploy Ladill Care / deploy (push) Failing after 57s
Add Care waiting-area TV displays with browser TTS voice.
Call-next and recall queue announcements for lobby screens without Ladill Queue.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 11:23:15 +00:00

93 lines
3.2 KiB
PHP

<?php
namespace App\Services\Care;
use App\Models\CareQueueTicket;
use App\Models\CareServicePoint;
use App\Models\CareVoiceAnnouncement;
class CareVoiceAnnouncementService
{
public function announceCalled(CareQueueTicket $ticket, CareServicePoint $point, ?string $locale = null): CareVoiceAnnouncement
{
$ticket->loadMissing(['organization', 'serviceQueue']);
$locale ??= 'en';
$message = $this->buildMessage($ticket, $point, $locale);
return CareVoiceAnnouncement::create([
'owner_ref' => $ticket->owner_ref,
'organization_id' => $ticket->organization_id,
'branch_id' => $ticket->serviceQueue->branch_id,
'ticket_id' => $ticket->id,
'locale' => $locale,
'message' => $message,
'voice' => 'female',
'volume' => 80,
'repeat_count' => 1,
'status' => 'pending',
]);
}
protected function buildMessage(CareQueueTicket $ticket, CareServicePoint $point, string $locale): string
{
$destination = $point->displayDestination();
$staff = trim((string) ($point->staff_display_name ?? ''));
$queueName = trim((string) ($ticket->serviceQueue?->name ?? ''));
$templates = config('care.announcement_templates', []);
if ($staff !== '') {
$richDestination = $queueName !== '' && ! str_contains(strtolower($destination), strtolower($queueName))
? trim($queueName.' '.$destination)
: $destination;
$template = $templates['with_staff'] ?? ':ticket, :staff, :destination.';
return rtrim(str_replace(
[':ticket', ':staff', ':destination', ':counter'],
[$ticket->ticket_number, $staff, $richDestination, $richDestination],
$template,
), '.').'.';
}
$template = $templates[$locale]
?? $templates['en']
?? 'Ticket :ticket, please proceed to :destination.';
return str_replace(
[':ticket', ':destination', ':counter'],
[$ticket->ticket_number, $destination, $destination],
$template,
);
}
/**
* @param list<int>|null $queueIds
* @return list<array<string, mixed>>
*/
public function pendingForBranch(int $branchId, ?array $queueIds = null, int $limit = 10): array
{
return CareVoiceAnnouncement::query()
->where('branch_id', $branchId)
->where('status', 'pending')
->when($queueIds, function ($query, array $queueIds) {
$query->whereHas('ticket', fn ($ticket) => $ticket->whereIn('service_queue_id', $queueIds));
})
->orderBy('id')
->limit($limit)
->get()
->map(fn (CareVoiceAnnouncement $a) => [
'id' => $a->id,
'message' => $a->message,
'locale' => $a->locale,
'voice' => $a->voice,
'volume' => $a->volume,
'repeat_count' => $a->repeat_count,
])
->all();
}
public function markPlayed(CareVoiceAnnouncement $announcement): void
{
$announcement->update(['status' => 'played', 'played_at' => now()]);
}
}