Files
minicrm/app/Services/TransferService.php
phuongtc fc9158b928
Some checks failed
Tests / PHP 8.3 (push) Has been cancelled
Tests / PHP 8.4 (push) Has been cancelled
Tests / PHP 8.5 (push) Has been cancelled
Refactor: Enforce type safety, fix close deadlock, implement assignee restrictions and notify admin fallbacks
2026-05-20 10:42:30 +00:00

93 lines
3.0 KiB
PHP

<?php
namespace App\Services;
use App\Models\Department;
use App\Models\Feedback;
use App\Models\TicketTransferLog;
use App\Models\User;
use App\Services\ActivityLogger;
use Illuminate\Validation\ValidationException;
class TransferService
{
public function transfer(
Feedback $feedback,
Department $toDepartment,
string $reason,
User $sender,
?int $newHandlerId = null,
): TicketTransferLog {
if (empty(trim($reason))) {
throw ValidationException::withMessages([
'reason' => __('feedback.transfer_reason_required'),
]);
}
if ($newHandlerId !== null) {
$handler = User::find($newHandlerId);
if (! $handler) {
throw ValidationException::withMessages([
'new_assignee_id' => __('feedback.user_not_found'),
]);
}
if ($handler->department_id !== $toDepartment->id && $toDepartment->manager_id !== $handler->id) {
throw ValidationException::withMessages([
'new_assignee_id' => __('feedback.handler_not_in_department'),
]);
}
}
$fromDepartmentId = $feedback->current_department_id;
$fromDepartmentName = $feedback->currentDepartment?->name ?? 'N/A';
$log = TicketTransferLog::create([
'feedback_id' => $feedback->id,
'from_department_id' => $fromDepartmentId,
'to_department_id' => $toDepartment->id,
'sender_id' => $sender->id,
'reason' => $reason,
]);
$feedback->update([
'current_department_id' => $toDepartment->id,
'assigned_to' => $newHandlerId ?? $toDepartment->manager_id ?? null,
]);
$this->notifyDepartmentManager($toDepartment, $feedback, $log, $sender);
ActivityLogger::log(
'transfer',
__('feedback.log_transfer', [
'title' => $feedback->title,
'from' => $fromDepartmentName,
'to' => $toDepartment->name,
]),
$feedback,
[
'feedback_id' => $feedback->id,
'from_department' => $fromDepartmentName,
'to_department' => $toDepartment->name,
'reason' => $reason,
],
);
return $log;
}
protected function notifyDepartmentManager(Department $department, Feedback $feedback, TicketTransferLog $log, User $sender): void
{
$manager = $department->manager;
if ($manager) {
$manager->notify(new \App\Notifications\TicketTransferred($feedback, $log, $sender));
} else {
// No manager! Notify admins
$admins = User::whereHas('roles', fn ($q) => $q->where('name', 'admin'))->get();
foreach ($admins as $admin) {
$admin->notify(new \App\Notifications\TicketTransferred($feedback, $log, $sender));
}
}
}
}