|
|
@@ -11,6 +11,7 @@ use App\Services\FileService;
|
|
|
use App\Services\NotificationService;
|
|
|
use Illuminate\Http\RedirectResponse;
|
|
|
use Illuminate\Http\Request;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
use Throwable;
|
|
|
|
|
|
class ChatMessageController extends Controller
|
|
|
@@ -23,6 +24,14 @@ class ChatMessageController extends Controller
|
|
|
): RedirectResponse {
|
|
|
$this->ensureCanViewOrder($order);
|
|
|
|
|
|
+ if ($this->isDeleteRequest($request)) {
|
|
|
+ $chatMessage = $this->resolveMessageForDeletion($request);
|
|
|
+ $this->ensureAdminCanDeleteMessage($chatMessage, $order, null);
|
|
|
+ $this->deleteMessage($chatMessage);
|
|
|
+
|
|
|
+ return redirect()->back()->with(['success' => 'Сообщение удалено.']);
|
|
|
+ }
|
|
|
+
|
|
|
return $this->storeMessage(
|
|
|
$request,
|
|
|
$fileService,
|
|
|
@@ -41,6 +50,14 @@ class ChatMessageController extends Controller
|
|
|
): RedirectResponse {
|
|
|
$this->ensureCanViewReclamation($reclamation);
|
|
|
|
|
|
+ if ($this->isDeleteRequest($request)) {
|
|
|
+ $chatMessage = $this->resolveMessageForDeletion($request);
|
|
|
+ $this->ensureAdminCanDeleteMessage($chatMessage, null, $reclamation);
|
|
|
+ $this->deleteMessage($chatMessage);
|
|
|
+
|
|
|
+ return redirect()->back()->with(['success' => 'Сообщение удалено.']);
|
|
|
+ }
|
|
|
+
|
|
|
return $this->storeMessage(
|
|
|
$request,
|
|
|
$fileService,
|
|
|
@@ -51,6 +68,22 @@ class ChatMessageController extends Controller
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ public function destroyForOrder(Order $order, ChatMessage $chatMessage): RedirectResponse
|
|
|
+ {
|
|
|
+ $this->ensureAdminCanDeleteMessage($chatMessage, $order, null);
|
|
|
+ $this->deleteMessage($chatMessage);
|
|
|
+
|
|
|
+ return redirect()->back()->with(['success' => 'Сообщение удалено.']);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function destroyForReclamation(Reclamation $reclamation, ChatMessage $chatMessage): RedirectResponse
|
|
|
+ {
|
|
|
+ $this->ensureAdminCanDeleteMessage($chatMessage, null, $reclamation);
|
|
|
+ $this->deleteMessage($chatMessage);
|
|
|
+
|
|
|
+ return redirect()->back()->with(['success' => 'Сообщение удалено.']);
|
|
|
+ }
|
|
|
+
|
|
|
private function storeMessage(
|
|
|
Request $request,
|
|
|
FileService $fileService,
|
|
|
@@ -60,6 +93,7 @@ class ChatMessageController extends Controller
|
|
|
string $filePath,
|
|
|
): RedirectResponse {
|
|
|
$isPrivileged = hasRole(Role::ADMIN . ',' . Role::MANAGER);
|
|
|
+ $isBrigadier = hasRole(Role::BRIGADIER);
|
|
|
|
|
|
$validated = $request->validate([
|
|
|
'message' => 'nullable|string',
|
|
|
@@ -72,7 +106,9 @@ class ChatMessageController extends Controller
|
|
|
]);
|
|
|
|
|
|
$notificationType = $validated['notification_type'] ?? ChatMessage::NOTIFICATION_NONE;
|
|
|
- if (!$isPrivileged) {
|
|
|
+ if ($isBrigadier) {
|
|
|
+ $notificationType = ChatMessage::NOTIFICATION_RESPONSIBLES;
|
|
|
+ } elseif (!$isPrivileged) {
|
|
|
$notificationType = ChatMessage::NOTIFICATION_NONE;
|
|
|
}
|
|
|
|
|
|
@@ -85,7 +121,9 @@ class ChatMessageController extends Controller
|
|
|
|
|
|
$recipientIds = [];
|
|
|
$targetUserId = null;
|
|
|
- if ($notificationType === ChatMessage::NOTIFICATION_USER) {
|
|
|
+ if ($isBrigadier) {
|
|
|
+ $recipientIds = $this->chatBrigadierRecipientIds($order, $reclamation, (int) auth()->id());
|
|
|
+ } elseif ($notificationType === ChatMessage::NOTIFICATION_USER) {
|
|
|
$targetUserId = (int) ($validated['target_user_id'] ?? 0);
|
|
|
if ($targetUserId < 1) {
|
|
|
return redirect()->back()->with(['danger' => 'Нужно выбрать пользователя для уведомления.']);
|
|
|
@@ -148,7 +186,7 @@ class ChatMessageController extends Controller
|
|
|
'reclamation.order',
|
|
|
'reclamation.user',
|
|
|
'reclamation.brigadier',
|
|
|
- ]), $recipientIds);
|
|
|
+ ]), $recipientIds, $isBrigadier);
|
|
|
}
|
|
|
} catch (Throwable $exception) {
|
|
|
report($exception);
|
|
|
@@ -159,6 +197,45 @@ class ChatMessageController extends Controller
|
|
|
return redirect()->back()->with(['success' => 'Сообщение отправлено.']);
|
|
|
}
|
|
|
|
|
|
+ private function ensureAdminCanDeleteMessage(
|
|
|
+ ChatMessage $chatMessage,
|
|
|
+ ?Order $order,
|
|
|
+ ?Reclamation $reclamation,
|
|
|
+ ): void {
|
|
|
+ abort_unless(hasRole(Role::ADMIN), 403);
|
|
|
+
|
|
|
+ if ($order && (int) $chatMessage->order_id !== (int) $order->id) {
|
|
|
+ abort(404);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($reclamation && (int) $chatMessage->reclamation_id !== (int) $reclamation->id) {
|
|
|
+ abort(404);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function deleteMessage(ChatMessage $chatMessage): void
|
|
|
+ {
|
|
|
+ DB::transaction(function () use ($chatMessage): void {
|
|
|
+ $chatMessage->notifiedUsers()->detach();
|
|
|
+ $chatMessage->files()->detach();
|
|
|
+ $chatMessage->delete();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private function isDeleteRequest(Request $request): bool
|
|
|
+ {
|
|
|
+ return $request->boolean('delete_message');
|
|
|
+ }
|
|
|
+
|
|
|
+ private function resolveMessageForDeletion(Request $request): ChatMessage
|
|
|
+ {
|
|
|
+ $validated = $request->validate([
|
|
|
+ 'chat_message_id' => 'required|integer|exists:chat_messages,id',
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return ChatMessage::query()->findOrFail((int) $validated['chat_message_id']);
|
|
|
+ }
|
|
|
+
|
|
|
private function ensureCanViewOrder(Order $order): void
|
|
|
{
|
|
|
if (hasRole(Role::BRIGADIER)) {
|
|
|
@@ -226,4 +303,20 @@ class ChatMessageController extends Controller
|
|
|
|
|
|
return $adminIds;
|
|
|
}
|
|
|
+
|
|
|
+ private function chatBrigadierRecipientIds(?Order $order, ?Reclamation $reclamation, int $senderId): array
|
|
|
+ {
|
|
|
+ $adminIds = User::query()
|
|
|
+ ->where('role', Role::ADMIN)
|
|
|
+ ->pluck('id')
|
|
|
+ ->map(static fn ($id) => (int) $id)
|
|
|
+ ->all();
|
|
|
+
|
|
|
+ $managerId = $order?->user_id ?: $reclamation?->user_id;
|
|
|
+
|
|
|
+ return array_values(array_unique(array_diff(array_filter([
|
|
|
+ ...$adminIds,
|
|
|
+ $managerId ? (int) $managerId : null,
|
|
|
+ ]), [$senderId])));
|
|
|
+ }
|
|
|
}
|