Files
ladill-queue/app/Services/Qms/QueueNotificationService.php
T
isaaccladandCursor d2f5ff11d2
Deploy Ladill Queue / deploy (push) Successful in 40s
Fix queue handoff so tickets keep their number across services.
Handoff now frees the counter, ends the service session, and requeues
the same ticket for the next department — critical for hospital flows
like doctor → lab.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 21:22:01 +00:00

98 lines
3.3 KiB
PHP

<?php
namespace App\Services\Qms;
use App\Models\Ticket;
use App\Services\Comms\EmailService;
use App\Services\Comms\SmsService;
use Illuminate\Support\Facades\Log;
class QueueNotificationService
{
public function __construct(
protected SmsService $sms,
protected EmailService $email,
) {}
public function ticketIssued(Ticket $ticket): void
{
$this->notify($ticket, 'issued', $this->message('issued', $ticket));
}
public function ticketCalled(Ticket $ticket): void
{
$counter = $ticket->counter?->name ?? 'the counter';
$this->notify($ticket, 'called', $this->message('called', $ticket, [':counter' => $counter]));
}
public function customersAhead(Ticket $ticket, int $ahead): void
{
if ($ahead > 2) {
return;
}
$this->notify($ticket, 'almost_ready', $this->message('almost_ready', $ticket, [':ahead' => (string) $ahead]));
}
public function ticketCompleted(Ticket $ticket): void
{
$feedbackUrl = route('qms.feedback.show', $ticket->qr_token);
$this->notify($ticket, 'completed', $this->message('completed', $ticket, [':feedback_url' => $feedbackUrl]));
}
public function ticketMissed(Ticket $ticket): void
{
$this->notify($ticket, 'missed', $this->message('missed', $ticket));
}
public function ticketTransferred(Ticket $ticket): void
{
$this->notify($ticket, 'transferred', $this->message('transferred', $ticket));
}
public function appointmentReminder(\App\Models\QueueAppointment $appointment): void
{
$message = "Reminder: your appointment at {$appointment->scheduled_at->format('M j, H:i')} is coming up. Ref: {$appointment->reference}";
$organization = $appointment->organization;
$this->sendToContact($appointment->customer_phone, $appointment->customer_email, $message, $organization);
}
protected function notify(Ticket $ticket, string $event, string $message): void
{
if (! data_get($ticket->serviceQueue?->settings, 'notifications_enabled', true)) {
return;
}
$organization = $ticket->organization ?? $ticket->serviceQueue?->organization;
$this->sendToContact($ticket->customer_phone, $ticket->customer_email, $message, $organization);
Log::info('Queue notification sent', [
'event' => $event,
'ticket' => $ticket->ticket_number,
]);
}
protected function sendToContact(?string $phone, ?string $email, string $message, ?\App\Models\Organization $organization = null): void
{
if ($phone) {
$this->sms->send($phone, $message);
}
if ($email) {
$this->email->send($email, 'Ladill Queue update', $message, null, null, $organization);
}
}
/**
* @param array<string, string> $replace
*/
protected function message(string $key, Ticket $ticket, array $replace = []): string
{
$template = config("qms.notification_templates.{$key}", 'Queue update for ticket :ticket.');
$replace = array_merge([
':ticket' => $ticket->ticket_number,
':queue' => $ticket->serviceQueue?->name ?? 'Queue',
], $replace);
return str_replace(array_keys($replace), array_values($replace), $template);
}
}