49 lines
1.4 KiB
PHP
49 lines
1.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Modules\Helpdesk\Services;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Modules\Helpdesk\Models\Category;
|
|
use Modules\Helpdesk\Models\Ticket;
|
|
|
|
final class AgentAssignmentService
|
|
{
|
|
/**
|
|
* Select the least-loaded available agent for a category.
|
|
*
|
|
* @param int|null $categoryId
|
|
* @return int|null
|
|
*/
|
|
public function selectAgentId(?int $categoryId): ?int
|
|
{
|
|
$query = User::query()
|
|
->where(static function (Builder $query): void {
|
|
$query->where('helpdesk_agent', true)->orWhere('helpdesk_admin', true);
|
|
})
|
|
->selectSub(
|
|
Ticket::query()
|
|
->selectRaw('count(*)')
|
|
->whereColumn('helpdesk_tickets.agent_id', 'users.id')
|
|
->whereNull('helpdesk_tickets.completed_at'),
|
|
'open_helpdesk_tickets_count'
|
|
);
|
|
|
|
if ($categoryId !== null) {
|
|
$category = Category::query()->find($categoryId);
|
|
$agentIds = $category?->agents()->pluck('users.id')->all() ?? [];
|
|
|
|
if ($agentIds !== []) {
|
|
$query->whereIn('id', $agentIds);
|
|
}
|
|
}
|
|
|
|
/** @var User|null $agent */
|
|
$agent = $query->orderBy('open_helpdesk_tickets_count')->orderBy('id')->first();
|
|
|
|
return $agent?->id;
|
|
}
|
|
}
|