148 خطوط
5.2 KiB
PHP
148 خطوط
5.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Lead;
|
|
use App\Models\User;
|
|
use App\Services\ActivityLogger;
|
|
use App\Services\AssignmentService;
|
|
use App\Support\AccessControl;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Gate;
|
|
|
|
class AssignmentController extends Controller
|
|
{
|
|
public function __construct(private AssignmentService $assignmentService) {}
|
|
|
|
public function assign(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'lead_id' => 'required|exists:leads,id',
|
|
'agent_id' => 'required|exists:users,id',
|
|
]);
|
|
$lead = Lead::findOrFail($validated['lead_id']);
|
|
$agent = User::findOrFail($validated['agent_id']);
|
|
if (!$this->canAssignToAgent($lead, $agent)) {
|
|
return response()->json(['message' => 'دسترسی غیرمجاز'], 403);
|
|
}
|
|
|
|
$lead = $this->assignmentService->assignToAgent(
|
|
$validated['lead_id'],
|
|
$validated['agent_id'],
|
|
auth()->id()
|
|
);
|
|
ActivityLogger::log('lead_owner_changed', "Lead {$lead->id} assigned to user {$agent->id}", $lead);
|
|
|
|
return response()->json($lead->load('assignedAgent'));
|
|
}
|
|
|
|
public function bulkAssign(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'lead_ids' => 'required|array|min:1',
|
|
'lead_ids.*' => 'exists:leads,id',
|
|
'agent_id' => 'required|exists:users,id',
|
|
]);
|
|
$agent = User::findOrFail($validated['agent_id']);
|
|
$leads = Lead::whereIn('id', $validated['lead_ids'])->get();
|
|
if ($leads->count() !== count(array_unique($validated['lead_ids'])) || $leads->contains(fn(Lead $lead) => !$this->canAssignToAgent($lead, $agent))) {
|
|
return response()->json(['message' => 'دسترسی غیرمجاز'], 403);
|
|
}
|
|
|
|
$leads = $this->assignmentService->bulkAssign(
|
|
$validated['lead_ids'],
|
|
$validated['agent_id'],
|
|
auth()->id()
|
|
);
|
|
ActivityLogger::log('lead_bulk_owner_changed', count($leads) . " leads assigned to user {$agent->id}");
|
|
|
|
return response()->json(['assigned' => count($leads)]);
|
|
}
|
|
|
|
public function roundRobin(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'lead_ids' => 'required|array|min:1',
|
|
'lead_ids.*' => 'exists:leads,id',
|
|
'agent_ids' => 'required|array|min:1',
|
|
'agent_ids.*' => 'exists:users,id',
|
|
]);
|
|
$agents = User::whereIn('id', $validated['agent_ids'])->get()->keyBy('id');
|
|
$leads = Lead::whereIn('id', $validated['lead_ids'])->get();
|
|
if (
|
|
$agents->count() !== count(array_unique($validated['agent_ids']))
|
|
|| $leads->count() !== count(array_unique($validated['lead_ids']))
|
|
|| $leads->contains(fn(Lead $lead) => Gate::denies('assign', $lead))
|
|
|| $agents->contains(fn(User $agent) => !$this->agentIsAssignable($agent))
|
|
) {
|
|
return response()->json(['message' => 'دسترسی غیرمجاز'], 403);
|
|
}
|
|
|
|
$leads = $this->assignmentService->roundRobin(
|
|
$validated['lead_ids'],
|
|
$validated['agent_ids'],
|
|
auth()->id()
|
|
);
|
|
ActivityLogger::log('lead_round_robin_owner_changed', count($leads) . ' leads assigned by round robin');
|
|
|
|
return response()->json(['assigned' => count($leads)]);
|
|
}
|
|
|
|
public function reassign(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'lead_id' => 'required|exists:leads,id',
|
|
'agent_id' => 'required|exists:users,id',
|
|
]);
|
|
$lead = Lead::findOrFail($validated['lead_id']);
|
|
$agent = User::findOrFail($validated['agent_id']);
|
|
if (!$this->canAssignToAgent($lead, $agent)) {
|
|
return response()->json(['message' => 'دسترسی غیرمجاز'], 403);
|
|
}
|
|
|
|
$lead = $this->assignmentService->assignToAgent(
|
|
$validated['lead_id'],
|
|
$validated['agent_id'],
|
|
auth()->id()
|
|
);
|
|
ActivityLogger::log('lead_owner_changed', "Lead {$lead->id} reassigned to user {$agent->id}", $lead);
|
|
|
|
return response()->json($lead->load('assignedAgent'));
|
|
}
|
|
|
|
public function returnToPool(int $leadId): JsonResponse
|
|
{
|
|
$leadModel = Lead::findOrFail($leadId);
|
|
Gate::authorize('assign', $leadModel);
|
|
|
|
$lead = $this->assignmentService->returnToPool($leadId);
|
|
return response()->json($lead);
|
|
}
|
|
|
|
private function canAssignToAgent(Lead $lead, User $agent): bool
|
|
{
|
|
return Gate::allows('assign', $lead) && $this->agentIsAssignable($agent);
|
|
}
|
|
|
|
private function agentIsAssignable(User $agent): bool
|
|
{
|
|
$user = auth()->user();
|
|
|
|
if (!$agent->hasRole('agent') || !$agent->is_active) {
|
|
return false;
|
|
}
|
|
|
|
if ($user?->hasRole('admin')) {
|
|
return true;
|
|
}
|
|
|
|
if ($user?->hasRole('supervisor')) {
|
|
return (bool) array_intersect(AccessControl::teamIds($user), $agent->teams()->pluck('teams.id')->all());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|