Deploy Ladill Queue / deploy (push) Successful in 56s
Phases 1–6: tickets, counters, displays, appointments, workflows, rules, analytics, reports, feedback, admin, device API, and Gitea deploy workflow for queue.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
50 lines
1.7 KiB
PHP
50 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Qms;
|
|
|
|
use App\Models\Branch;
|
|
use App\Models\Ticket;
|
|
use App\Support\DatabaseTime;
|
|
|
|
class DashboardStats
|
|
{
|
|
/**
|
|
* @return array<string, int|float>
|
|
*/
|
|
public function forOrganization(string $ownerRef, int $organizationId, ?int $branchId = null): array
|
|
{
|
|
$ticketQuery = Ticket::owned($ownerRef)
|
|
->where('organization_id', $organizationId)
|
|
->when($branchId, fn ($q) => $q->where('branch_id', $branchId));
|
|
|
|
$todayQuery = (clone $ticketQuery)->whereDate('issued_at', today());
|
|
|
|
$waiting = (clone $ticketQuery)->where('status', 'waiting')->count();
|
|
$serving = (clone $ticketQuery)->whereIn('status', ['called', 'serving'])->count();
|
|
$servedToday = (clone $todayQuery)->where('status', 'completed')->count();
|
|
$noShowsToday = (clone $todayQuery)->where('status', 'no_show')->count();
|
|
|
|
$waitDiff = DatabaseTime::diffSeconds('issued_at', 'called_at');
|
|
$avgWait = (clone $todayQuery)
|
|
->where('status', 'completed')
|
|
->whereNotNull('called_at')
|
|
->selectRaw("AVG({$waitDiff}) as avg_wait")
|
|
->value('avg_wait');
|
|
|
|
$activeBranches = Branch::owned($ownerRef)
|
|
->where('organization_id', $organizationId)
|
|
->where('is_active', true)
|
|
->when($branchId, fn ($q) => $q->where('id', $branchId))
|
|
->count();
|
|
|
|
return [
|
|
'waiting' => $waiting,
|
|
'serving' => $serving,
|
|
'served_today' => $servedToday,
|
|
'no_shows_today' => $noShowsToday,
|
|
'avg_wait_seconds' => (int) round((float) $avgWait),
|
|
'active_branches' => $activeBranches,
|
|
];
|
|
}
|
|
}
|