|
@@ -0,0 +1,477 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+namespace App\Services;
|
|
|
|
|
+
|
|
|
|
|
+use App\Events\SendPersistentNotificationEvent;
|
|
|
|
|
+use App\Helpers\DateHelper;
|
|
|
|
|
+use App\Jobs\SendUserNotificationChannelJob;
|
|
|
|
|
+use App\Models\NotificationDeliveryLog;
|
|
|
|
|
+use App\Models\Order;
|
|
|
|
|
+use App\Models\Reclamation;
|
|
|
|
|
+use App\Models\Role;
|
|
|
|
|
+use App\Models\Schedule;
|
|
|
|
|
+use App\Models\User;
|
|
|
|
|
+use App\Models\UserNotification;
|
|
|
|
|
+use App\Models\UserNotificationSetting;
|
|
|
|
|
+use App\Notifications\FireBaseNotification;
|
|
|
|
|
+use Illuminate\Database\Eloquent\Collection;
|
|
|
|
|
+use Illuminate\Support\Facades\Mail;
|
|
|
|
|
+use Illuminate\Support\Str;
|
|
|
|
|
+
|
|
|
|
|
+class NotificationService
|
|
|
|
|
+{
|
|
|
|
|
+ public function notifyOrderCreated(Order $order): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $statusName = $order->orderStatus?->name ?? (Order::STATUS_NAMES[$order->order_status_id] ?? '-');
|
|
|
|
|
+
|
|
|
|
|
+ $this->notifyOrderEvent(
|
|
|
|
|
+ $order,
|
|
|
|
|
+ UserNotification::EVENT_CREATED,
|
|
|
|
|
+ 'Площадки',
|
|
|
|
|
+ sprintf('Добавлена новая площадка %s', $order->object_address),
|
|
|
|
|
+ sprintf(
|
|
|
|
|
+ 'Добавлена новая площадка <a href="%s">%s</a>.',
|
|
|
|
|
+ route('order.show', ['order' => $order->id]),
|
|
|
|
|
+ e($order->object_address)
|
|
|
|
|
+ ),
|
|
|
|
|
+ $statusName,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function notifyOrderStatusChanged(Order $order): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $statusName = $order->orderStatus?->name ?? (Order::STATUS_NAMES[$order->order_status_id] ?? '-');
|
|
|
|
|
+
|
|
|
|
|
+ $this->notifyOrderEvent(
|
|
|
|
|
+ $order,
|
|
|
|
|
+ UserNotification::EVENT_STATUS_CHANGED,
|
|
|
|
|
+ 'Площадки',
|
|
|
|
|
+ sprintf('Статус площадки %s изменен на %s', $order->object_address, $statusName),
|
|
|
|
|
+ sprintf(
|
|
|
|
|
+ 'Статус площадки <a href="%s">%s</a> изменен на %s.',
|
|
|
|
|
+ route('order.show', ['order' => $order->id]),
|
|
|
|
|
+ e($order->object_address),
|
|
|
|
|
+ e($statusName)
|
|
|
|
|
+ ),
|
|
|
|
|
+ $statusName,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function notifyReclamationCreated(Reclamation $reclamation): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $order = $reclamation->order;
|
|
|
|
|
+ if (!$order) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $message = sprintf(
|
|
|
|
|
+ 'Добавлена новая рекламация по адресу %s #%d',
|
|
|
|
|
+ $order->object_address,
|
|
|
|
|
+ $reclamation->id,
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $messageHtml = sprintf(
|
|
|
|
|
+ 'Добавлена новая рекламация по адресу <a href="%s">%s</a> <a href="%s">#%d</a>.',
|
|
|
|
|
+ route('order.show', ['order' => $order->id]),
|
|
|
|
|
+ e($order->object_address),
|
|
|
|
|
+ route('reclamations.show', ['reclamation' => $reclamation->id]),
|
|
|
|
|
+ $reclamation->id,
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $this->notifyReclamationEvent(
|
|
|
|
|
+ $reclamation,
|
|
|
|
|
+ UserNotification::EVENT_CREATED,
|
|
|
|
|
+ 'Рекламации',
|
|
|
|
|
+ $message,
|
|
|
|
|
+ $messageHtml,
|
|
|
|
|
+ (int)$reclamation->status_id,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function notifyReclamationStatusChanged(Reclamation $reclamation): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $order = $reclamation->order;
|
|
|
|
|
+ if (!$order) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $statusName = $reclamation->status?->name ?? (Reclamation::STATUS_NAMES[$reclamation->status_id] ?? '-');
|
|
|
|
|
+
|
|
|
|
|
+ $message = sprintf(
|
|
|
|
|
+ 'Статус рекламации %s #%d изменен на %s',
|
|
|
|
|
+ $order->object_address,
|
|
|
|
|
+ $reclamation->id,
|
|
|
|
|
+ $statusName,
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $messageHtml = sprintf(
|
|
|
|
|
+ 'Статус рекламации по адресу <a href="%s">%s</a> <a href="%s">#%d</a> изменен на %s.',
|
|
|
|
|
+ route('order.show', ['order' => $order->id]),
|
|
|
|
|
+ e($order->object_address),
|
|
|
|
|
+ route('reclamations.show', ['reclamation' => $reclamation->id]),
|
|
|
|
|
+ $reclamation->id,
|
|
|
|
|
+ e($statusName),
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $this->notifyReclamationEvent(
|
|
|
|
|
+ $reclamation,
|
|
|
|
|
+ UserNotification::EVENT_STATUS_CHANGED,
|
|
|
|
|
+ 'Рекламации',
|
|
|
|
|
+ $message,
|
|
|
|
|
+ $messageHtml,
|
|
|
|
|
+ (int)$reclamation->status_id,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function notifyScheduleAdded(Schedule $schedule): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $sourceKey = $this->sourceToSettingKey((string)$schedule->source);
|
|
|
|
|
+ if (!$sourceKey) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $brigadierName = $schedule->brigadier?->name ?? '-';
|
|
|
|
|
+ $date = DateHelper::getHumanDate((string)$schedule->installation_date, true);
|
|
|
|
|
+
|
|
|
|
|
+ $message = sprintf(
|
|
|
|
|
+ '%s добавлено в график монтажей на %s, Бригадир %s.',
|
|
|
|
|
+ $schedule->object_address,
|
|
|
|
|
+ $date,
|
|
|
|
|
+ $brigadierName,
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $orderLink = $schedule->order_id
|
|
|
|
|
+ ? route('order.show', ['order' => $schedule->order_id])
|
|
|
|
|
+ : route('schedule.index');
|
|
|
|
|
+
|
|
|
|
|
+ $messageHtml = sprintf(
|
|
|
|
|
+ '<a href="%s">%s</a> добавлено в график монтажей на %s, Бригадир %s.',
|
|
|
|
|
+ $orderLink,
|
|
|
|
|
+ e($schedule->object_address),
|
|
|
|
|
+ e($date),
|
|
|
|
|
+ e($brigadierName),
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $users = $this->scheduleRecipients($schedule);
|
|
|
|
|
+ foreach ($users as $user) {
|
|
|
|
|
+ $settings = $this->settingsForUser($user->id);
|
|
|
|
|
+ if (!$settings->isSectionEnabled('schedule_settings')) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $channels = $settings->getChannelsForKey('schedule_settings', $sourceKey);
|
|
|
|
|
+ if (empty($channels)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $notification = $this->createInAppNotification(
|
|
|
|
|
+ $user,
|
|
|
|
|
+ UserNotification::TYPE_SCHEDULE,
|
|
|
|
|
+ UserNotification::EVENT_SCHEDULE_ADDED,
|
|
|
|
|
+ 'График монтажей',
|
|
|
|
|
+ $message,
|
|
|
|
|
+ $messageHtml,
|
|
|
|
|
+ [
|
|
|
|
|
+ 'schedule_id' => $schedule->id,
|
|
|
|
|
+ 'source' => $schedule->source,
|
|
|
|
|
+ ],
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $this->dispatchDeliveryJobs($notification, [
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_BROWSER => !empty($channels['browser']),
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_PUSH => !empty($channels['push']),
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_EMAIL => !empty($channels['email']),
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function deliverChannel(int $userNotificationId, string $channel, int $attempt): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $notification = UserNotification::query()->with('user')->find($userNotificationId);
|
|
|
|
|
+ if (!$notification || !$notification->user) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ if ($channel === NotificationDeliveryLog::CHANNEL_BROWSER) {
|
|
|
|
|
+ event(new SendPersistentNotificationEvent($notification->user_id, [
|
|
|
|
|
+ 'id' => $notification->id,
|
|
|
|
|
+ 'type' => $notification->type,
|
|
|
|
|
+ 'title' => $notification->title,
|
|
|
|
|
+ 'message' => $notification->message,
|
|
|
|
|
+ 'message_html' => $notification->message_html,
|
|
|
|
|
+ 'created_at' => $notification->created_at?->toDateTimeString(),
|
|
|
|
|
+ ]));
|
|
|
|
|
+
|
|
|
|
|
+ $this->createLog($notification, $channel, NotificationDeliveryLog::STATUS_SENT, $attempt, null);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($channel === NotificationDeliveryLog::CHANNEL_PUSH) {
|
|
|
|
|
+ if (!$notification->user->token_fcm) {
|
|
|
|
|
+ $this->createLog($notification, $channel, NotificationDeliveryLog::STATUS_SKIPPED, $attempt, 'Отсутствует token_fcm');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $notification->user->notify(new FireBaseNotification($notification->title, Str::limit(strip_tags($notification->message), 200)));
|
|
|
|
|
+ $this->createLog($notification, $channel, NotificationDeliveryLog::STATUS_SENT, $attempt, null);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($channel === NotificationDeliveryLog::CHANNEL_EMAIL) {
|
|
|
|
|
+ $email = $notification->user->notification_email;
|
|
|
|
|
+ if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
|
|
|
+ $this->createLog($notification, $channel, NotificationDeliveryLog::STATUS_SKIPPED, $attempt, 'Отсутствует валидный notification_email');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Mail::raw($notification->message, function ($mail) use ($email, $notification) {
|
|
|
|
|
+ $mail->to($email)
|
|
|
|
|
+ ->subject($notification->title);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ $this->createLog($notification, $channel, NotificationDeliveryLog::STATUS_SENT, $attempt, null);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $this->createLog($notification, $channel, NotificationDeliveryLog::STATUS_SKIPPED, $attempt, 'Неизвестный канал');
|
|
|
|
|
+ } catch (\Throwable $exception) {
|
|
|
|
|
+ $this->createLog($notification, $channel, NotificationDeliveryLog::STATUS_FAILED, $attempt, $exception->getMessage());
|
|
|
|
|
+ throw $exception;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function markDeadLetter(int $userNotificationId, string $channel, int $attempt, ?string $error = null): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $notification = UserNotification::query()->find($userNotificationId);
|
|
|
|
|
+ if (!$notification) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $this->createLog($notification, $channel, NotificationDeliveryLog::STATUS_DEAD_LETTER, $attempt, $error);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function notifyOrderEvent(
|
|
|
|
|
+ Order $order,
|
|
|
|
|
+ string $event,
|
|
|
|
|
+ string $title,
|
|
|
|
|
+ string $message,
|
|
|
|
|
+ string $messageHtml,
|
|
|
|
|
+ string $statusName,
|
|
|
|
|
+ ): void {
|
|
|
|
|
+ $users = $this->orderRecipients($order);
|
|
|
|
|
+ $statusId = (int) $order->order_status_id;
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($users as $user) {
|
|
|
|
|
+ $settings = $this->settingsForUser($user->id);
|
|
|
|
|
+ if (!$settings->isSectionEnabled('order_settings')) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $channels = $settings->getChannelsForKey('order_settings', $statusId);
|
|
|
|
|
+ if (empty($channels)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $notification = $this->createInAppNotification(
|
|
|
|
|
+ $user,
|
|
|
|
|
+ UserNotification::TYPE_PLATFORM,
|
|
|
|
|
+ $event,
|
|
|
|
|
+ $title,
|
|
|
|
|
+ $message,
|
|
|
|
|
+ $messageHtml,
|
|
|
|
|
+ [
|
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
|
+ 'status' => $statusName,
|
|
|
|
|
+ ],
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $this->dispatchDeliveryJobs($notification, [
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_BROWSER => !empty($channels['browser']),
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_PUSH => !empty($channels['push']),
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_EMAIL => !empty($channels['email']),
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function notifyReclamationEvent(
|
|
|
|
|
+ Reclamation $reclamation,
|
|
|
|
|
+ string $event,
|
|
|
|
|
+ string $title,
|
|
|
|
|
+ string $message,
|
|
|
|
|
+ string $messageHtml,
|
|
|
|
|
+ int $statusId,
|
|
|
|
|
+ ): void {
|
|
|
|
|
+ $users = $this->reclamationRecipients($reclamation);
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($users as $user) {
|
|
|
|
|
+ $settings = $this->settingsForUser($user->id);
|
|
|
|
|
+ if (!$settings->isSectionEnabled('reclamation_settings')) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $channels = $settings->getChannelsForKey('reclamation_settings', $statusId);
|
|
|
|
|
+ if (empty($channels)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $notification = $this->createInAppNotification(
|
|
|
|
|
+ $user,
|
|
|
|
|
+ UserNotification::TYPE_RECLAMATION,
|
|
|
|
|
+ $event,
|
|
|
|
|
+ $title,
|
|
|
|
|
+ $message,
|
|
|
|
|
+ $messageHtml,
|
|
|
|
|
+ [
|
|
|
|
|
+ 'reclamation_id' => $reclamation->id,
|
|
|
|
|
+ 'status_id' => $statusId,
|
|
|
|
|
+ ],
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $this->dispatchDeliveryJobs($notification, [
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_BROWSER => !empty($channels['browser']),
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_PUSH => !empty($channels['push']),
|
|
|
|
|
+ NotificationDeliveryLog::CHANNEL_EMAIL => !empty($channels['email']),
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function dispatchDeliveryJobs(UserNotification $notification, array $channels): void
|
|
|
|
|
+ {
|
|
|
|
|
+ foreach ($channels as $channel => $enabled) {
|
|
|
|
|
+ if (!$enabled) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ SendUserNotificationChannelJob::dispatch($notification->id, $channel);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function createInAppNotification(
|
|
|
|
|
+ User $user,
|
|
|
|
|
+ string $type,
|
|
|
|
|
+ string $event,
|
|
|
|
|
+ string $title,
|
|
|
|
|
+ string $message,
|
|
|
|
|
+ string $messageHtml,
|
|
|
|
|
+ array $payload,
|
|
|
|
|
+ ): UserNotification {
|
|
|
|
|
+ $notification = UserNotification::query()->create([
|
|
|
|
|
+ 'user_id' => $user->id,
|
|
|
|
|
+ 'type' => $type,
|
|
|
|
|
+ 'event' => $event,
|
|
|
|
|
+ 'title' => $title,
|
|
|
|
|
+ 'message' => $message,
|
|
|
|
|
+ 'message_html' => $messageHtml,
|
|
|
|
|
+ 'data' => $payload,
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $this->createLog($notification, NotificationDeliveryLog::CHANNEL_IN_APP, NotificationDeliveryLog::STATUS_SENT, 1, null);
|
|
|
|
|
+
|
|
|
|
|
+ return $notification;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function createLog(
|
|
|
|
|
+ UserNotification $notification,
|
|
|
|
|
+ string $channel,
|
|
|
|
|
+ string $status,
|
|
|
|
|
+ int $attempt,
|
|
|
|
|
+ ?string $error,
|
|
|
|
|
+ ): void {
|
|
|
|
|
+ NotificationDeliveryLog::query()->create([
|
|
|
|
|
+ 'user_notification_id' => $notification->id,
|
|
|
|
|
+ 'user_id' => $notification->user_id,
|
|
|
|
|
+ 'channel' => $channel,
|
|
|
|
|
+ 'status' => $status,
|
|
|
|
|
+ 'attempt' => $attempt,
|
|
|
|
|
+ 'message' => $notification->message,
|
|
|
|
|
+ 'error' => $error,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function settingsForUser(int $userId): UserNotificationSetting
|
|
|
|
|
+ {
|
|
|
|
|
+ return UserNotificationSetting::query()->firstOrCreate(
|
|
|
|
|
+ ['user_id' => $userId],
|
|
|
|
|
+ UserNotificationSetting::defaultsForUser($userId),
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function orderRecipients(Order $order): Collection
|
|
|
|
|
+ {
|
|
|
|
|
+ $query = User::query()
|
|
|
|
|
+ ->whereIn('role', [Role::ADMIN, Role::ASSISTANT_HEAD, Role::WAREHOUSE_HEAD]);
|
|
|
|
|
+
|
|
|
|
|
+ if ($order->user_id) {
|
|
|
|
|
+ $query->orWhere('id', $order->user_id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $query->distinct()->get();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function reclamationRecipients(Reclamation $reclamation): Collection
|
|
|
|
|
+ {
|
|
|
|
|
+ $query = User::query()
|
|
|
|
|
+ ->whereIn('role', [Role::ADMIN, Role::ASSISTANT_HEAD, Role::WAREHOUSE_HEAD]);
|
|
|
|
|
+
|
|
|
|
|
+ $managerId = $reclamation->order?->user_id ?: $reclamation->user_id;
|
|
|
|
|
+ if ($managerId) {
|
|
|
|
|
+ $query->orWhere('id', $managerId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $query->distinct()->get();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function scheduleRecipients(Schedule $schedule): Collection
|
|
|
|
|
+ {
|
|
|
|
|
+ $query = User::query()
|
|
|
|
|
+ ->whereIn('role', [Role::ADMIN, Role::ASSISTANT_HEAD, Role::WAREHOUSE_HEAD]);
|
|
|
|
|
+
|
|
|
|
|
+ if ($schedule->brigadier_id) {
|
|
|
|
|
+ $query->orWhere('id', $schedule->brigadier_id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $managerId = null;
|
|
|
|
|
+ if ((string)$schedule->source === 'Площадки' && $schedule->order_id) {
|
|
|
|
|
+ $managerId = Order::query()
|
|
|
|
|
+ ->withoutGlobalScope(\App\Models\Scopes\YearScope::class)
|
|
|
|
|
+ ->where('id', $schedule->order_id)
|
|
|
|
|
+ ->value('user_id');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ((string)$schedule->source === 'Рекламации') {
|
|
|
|
|
+ $reclamationId = $this->extractReclamationId((string)$schedule->address_code);
|
|
|
|
|
+ if ($reclamationId) {
|
|
|
|
|
+ $reclamation = Reclamation::query()
|
|
|
|
|
+ ->withoutGlobalScope(\App\Models\Scopes\YearScope::class)
|
|
|
|
|
+ ->with('order')
|
|
|
|
|
+ ->find($reclamationId);
|
|
|
|
|
+ $managerId = $reclamation?->order?->user_id ?: $reclamation?->user_id;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($managerId) {
|
|
|
|
|
+ $query->orWhere('id', $managerId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $query->distinct()->get();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function extractReclamationId(string $addressCode): ?int
|
|
|
|
|
+ {
|
|
|
|
|
+ if (preg_match('/^РЕКЛ-(\d+)$/u', $addressCode, $matches)) {
|
|
|
|
|
+ return (int)$matches[1];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function sourceToSettingKey(string $source): ?string
|
|
|
|
|
+ {
|
|
|
|
|
+ return match ($source) {
|
|
|
|
|
+ 'Площадки' => 'platform',
|
|
|
|
|
+ 'Рекламации' => 'reclamation',
|
|
|
|
|
+ default => null,
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+}
|