Forráskód Böngészése

refactor: modulo de notificacao

Gustavo Mantovani 2 hete
szülő
commit
404675b426

+ 4 - 0
app/Http/Controllers/NotificationController.php

@@ -11,8 +11,12 @@ class NotificationController extends Controller
 {
     public function index(): JsonResponse
     {
+
+
         $user = Auth::user();
 
+
+
         $notifications = Notification::where('user_id', $user->id)
             ->orderBy('read', 'asc')
             ->orderBy('created_at', 'desc')

+ 2 - 3
app/Jobs/FinishScheduleJob.php

@@ -9,6 +9,7 @@ use App\Models\Provider;
 use App\Models\Schedule;
 use App\Models\User;
 use App\Services\EmailService;
+use App\Services\ScheduleService;
 use Carbon\Carbon;
 use Illuminate\Bus\Queueable;
 use Illuminate\Contracts\Queue\ShouldQueue;
@@ -68,9 +69,7 @@ class FinishScheduleJob implements ShouldQueue
 
             Log::channel('schedule_end_jobs')->info('Validado com sucesso, atualizado agendamento id: '.$schedule->id.' para status finalizado');
 
-            $schedule->update([
-                'status' => 'finished',
-            ]);
+            app(ScheduleService::class)->updateStatus($schedule->id, 'finished');
 
             $provider = Provider::find($schedule->provider_id);
 

+ 1 - 0
app/Jobs/StartScheduleJob.php

@@ -7,6 +7,7 @@ use Carbon\Carbon;
 use Illuminate\Bus\Queueable;
 use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Foundation\Bus\Dispatchable;
+use App\Services\ScheduleService;
 use Illuminate\Queue\InteractsWithQueue;
 use Illuminate\Queue\SerializesModels;
 use Illuminate\Support\Facades\Log;

+ 72 - 2
app/Services/CustomScheduleService.php

@@ -11,6 +11,7 @@ use App\Models\Schedule;
 use App\Models\ScheduleProposal;
 use App\Models\ScheduleRefuse;
 use App\Rules\ScheduleBusinessRules;
+use App\Services\NotificationService;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
@@ -364,6 +365,32 @@ class CustomScheduleService
 
         $this->checkProviderAvailability($providerId, $schedule);
 
+        $provider = Provider::with([
+            'user'
+        ])->findOrFail($providerId);
+
+        $schedule->load([
+            'client.user'
+        ]);
+
+        $notificationService = app(NotificationService::class);
+
+        $notificationService->create([
+            'title' => 'Nova proposta recebida!',
+
+            'description' =>
+            $provider->user->name .
+                ' enviou uma proposta para seu agendamento sob medida.',
+
+            'origin' => 'schedule',
+
+            'origin_id' => $schedule->id,
+
+            'type' => NotificationTypeEnum::SCHEDULE_PROVIDER_CLIENT_NEW_SOLICITATION->value,
+
+            'user_id' => $schedule->client->user_id,
+        ]);
+
         return ScheduleProposal::create([
             'schedule_id' => $scheduleId,
             'provider_id' => $providerId,
@@ -405,10 +432,10 @@ class CustomScheduleService
 
             $schedule->update([
                 'provider_id' => $proposal->provider_id,
-                'status'      => 'accepted',
             ]);
 
-            $notificationService = app(NotificationService::class);
+            $schedule->refresh();
+            $schedule->load(['provider.user', 'client.user']);
 
             $notificationService->create([
                 'title' => 'Proposta aceita!',
@@ -424,6 +451,8 @@ class CustomScheduleService
                 'user_id' => $provider->user_id,
             ]);
 
+            app(ScheduleService::class)->updateStatus($schedule->id, 'accepted');
+
             ScheduleProposal::where('schedule_id', $schedule->id)
                 ->where('id', '!=', $proposalId)
                 ->delete();
@@ -442,6 +471,25 @@ class CustomScheduleService
                 'provider_id' => $proposal->provider_id,
             ]);
 
+            $notificationService = app(NotificationService::class);
+
+            $notificationService->create([
+                'title' => 'Proposta recusada!',
+
+                'description' =>
+                'O cliente recusou sua proposta de diária.',
+
+                'origin' => 'schedule',
+
+                'origin_id' => $proposal->schedule_id,
+
+                'type' =>
+                NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_REFUSED->value,
+
+                'user_id' => $proposal->provider->user_id,
+            ]);
+
+
             $proposal->delete();
 
             return true;
@@ -641,11 +689,33 @@ class CustomScheduleService
 
     public function refuseOpportunity($scheduleId, $providerId)
     {
+
+        $schedule = Schedule::with(['client.user'])->findOrFail($scheduleId);
+
+        $provider = Provider::with(['user'])->findOrFail($providerId);
+        
         $schedule_refuse = ScheduleRefuse::create([
             'schedule_id' => $scheduleId,
             'provider_id' => $providerId,
         ]);
 
+        $notificationService = app(NotificationService::class);
+
+        $notificationService->create([
+            'title' => 'Oportunidade recusada!',
+
+            'description' => $provider->user->name . ' recusou sua solicitação sob medida.',
+
+            'origin' => 'schedule',
+
+            'origin_id' => $scheduleId,
+
+            'type' =>
+            NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_REFUSED->value,
+
+            'user_id' => $schedule->client->user_id,
+        ]);
+
         return $schedule_refuse;
     }
 }

+ 295 - 180
app/Services/ScheduleService.php

@@ -7,6 +7,8 @@ use App\Jobs\StartScheduleJob;
 use App\Models\Provider;
 use App\Models\Schedule;
 use App\Rules\ScheduleBusinessRules;
+use App\Services\NotificationService;
+use App\Enums\UserTypeEnum;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
@@ -78,8 +80,10 @@ class ScheduleService
 
     public function update($id, array $data)
     {
-        $schedule = Schedule::findOrFail($id);
 
+        unset($data['status']);
+
+        $schedule = Schedule::with(['provider.user', 'client.user', 'address'])->findOrFail($id);
         if (isset($data['provider_id']) || isset($data['period_type'])) {
             $providerId = $data['provider_id'] ?? $schedule->provider_id;
             $periodType = $data['period_type'] ?? $schedule->period_type;
@@ -111,6 +115,296 @@ class ScheduleService
 
     //
 
+    public function updateStatus($id, string $status)
+    {
+        try {
+            DB::beginTransaction();
+            $schedule = Schedule::with(['provider.user', 'client.user', 'address'])->findOrFail($id);
+
+            $allowedTransitions = [
+                'pending' => ['accepted', 'rejected', 'cancelled'],
+                'accepted'  => ['paid', 'cancelled'],
+                'paid'      => ['cancelled', 'started'],
+                'started'   => ['finished'],
+                'rejected'  => [],
+                'cancelled' => [],
+                'finished'  => [],
+            ];
+
+            $currentStatus = $schedule->status;
+
+            if (! isset($allowedTransitions[$currentStatus])) {
+                throw new \Exception('Status atual inválido.');
+            }
+
+            if (! in_array($status, $allowedTransitions[$currentStatus])) {
+                throw new \Exception("Transição de status não permitida: {$currentStatus} → {$status}");
+            }
+
+            $schedule->update(['status' => $status]);
+            $schedule->refresh();
+
+            $currentStatus = $schedule->status;
+        
+            switch ($status) {
+
+                case 'pending':
+                    break;
+
+                case 'accepted':
+
+                    $notificationService = app(NotificationService::class);
+
+                    switch (Auth::user()->type) {
+
+                        case UserTypeEnum::PROVIDER:
+
+                            $notificationService->create([
+                                'title' => 'Agendamento aceito!',
+
+                                'description' =>
+                                $schedule->provider->user->name .
+                                    ' aceitou sua solicitação de diária.',
+
+                                'origin' => 'schedule',
+
+                                'origin_id' => $schedule->id,
+
+                                'type' =>
+                                NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_ACCEPTED->value,
+
+                                'user_id' => $schedule->client->user_id,
+                            ]);
+
+                            break;
+
+                        case UserTypeEnum::CLIENT:
+
+                            if ($schedule->provider_id) {
+
+                                $notificationService->create([
+                                    'title' => 'Proposta aceita!',
+
+                                    'description' =>
+                                    'O cliente aceitou sua proposta de diária.',
+
+                                    'origin' => 'schedule',
+
+                                    'origin_id' => $schedule->id,
+
+                                    'type' =>
+                                    NotificationTypeEnum::SCHEDULE_PROVIDER_CLIENT_PROPOSAL_ACCEPTED->value,
+
+                                    'user_id' => $schedule->provider->user_id,
+                                ]);
+                            }
+
+                            break;
+
+                        default:
+                            break;
+                    }
+
+                    break;
+
+                case 'cancelled':
+
+                    $notificationService = app(NotificationService::class);
+
+                    switch (Auth::user()->type) {
+
+                        case UserTypeEnum::CLIENT:
+
+                            $notificationService->create([
+                                'title' => 'Agendamento cancelado!',
+
+                                'description' =>
+                                'O cliente cancelou o agendamento.',
+
+                                'origin' => 'schedule',
+
+                                'origin_id' => $schedule->id,
+
+                                'type' =>
+                                NotificationTypeEnum::SCHEDULE_PROVIDER_CLIENT_CANCELLED->value,
+
+                                'user_id' => $schedule->provider->user_id,
+                            ]);
+
+                            break;
+
+                        case UserTypeEnum::PROVIDER:
+
+                            $notificationService->create([
+                                'title' => 'Agendamento cancelado!',
+
+                                'description' =>
+                                $schedule->provider->user->name .
+                                    ' cancelou sua solicitação de diária.',
+
+                                'origin' => 'schedule',
+
+                                'origin_id' => $schedule->id,
+
+                                'type' =>
+                                NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_CANCELLED->value,
+
+                                'user_id' => $schedule->client->user_id,
+                            ]);
+
+                            break;
+
+                        default:
+                            break;
+                    }
+
+                    break;
+
+                case 'started':
+
+                    $notificationService = app(NotificationService::class);
+
+                    // CLIENTE
+                    $notificationService->create([
+                        'title' => 'Diarista a caminho!',
+
+                        'description' =>
+                        'Informe o código ' . $schedule->code . ' para liberar o início do serviço.',
+
+                        'origin' => 'schedule',
+
+                        'origin_id' => $schedule->id,
+
+                        'type' =>
+                        NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_COMING->value,
+
+                        'user_id' => $schedule->client->user_id,
+                    ]);
+
+                    // PRESTADOR
+                    $notificationService->create([
+                        'title' => 'Início do serviço!',
+
+                        'description' =>
+                        'Solicite o código ao cliente para iniciar a diária.',
+
+                        'origin' => 'schedule',
+
+                        'origin_id' => $schedule->id,
+
+                        'type' =>
+                        NotificationTypeEnum::SCHEDULE_PROVIDER_START->value,
+
+                        'user_id' => $schedule->provider->user_id,
+                    ]);
+
+                    break;
+
+                case 'finished':
+
+                    $notificationService = app(NotificationService::class);
+
+                    // CLIENTE
+                    $notificationService->create([
+                        'title' => 'Serviço finalizado!',
+
+                        'description' =>
+                        'Sua diária foi finalizada com sucesso.',
+
+                        'origin' => 'schedule',
+
+                        'origin_id' => $schedule->id,
+
+                        'type' =>
+                        NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_FINISHED->value,
+
+                        'user_id' => $schedule->client->user_id,
+                    ]);
+
+                    break;
+
+                case 'paid':
+
+                    $notificationService = app(NotificationService::class);
+
+                    switch (Auth::user()->type) {
+
+                        case UserTypeEnum::CLIENT:
+
+                            if ($schedule->provider_id) {
+
+                                $notificationService->create([
+                                    'title' => 'Pagamento confirmado!',
+
+                                    'description' =>
+                                    'O cliente confirmou o pagamento da diária.',
+
+                                    'origin' => 'schedule',
+
+                                    'origin_id' => $schedule->id,
+
+                                    'type' =>
+                                    NotificationTypeEnum::SCHEDULE_PROVIDER_START->value,
+
+                                    'user_id' => $schedule->provider->user_id,
+                                ]);
+                            }
+
+                            break;
+
+                        default:
+                            break;
+                    }
+
+                    $date_cleaned = Carbon::parse($schedule->date)
+                        ->format('Y-m-d');
+
+                    $date_time_dispatch = Carbon::parse(
+                        $date_cleaned . ' ' . $schedule->start_time
+                    )->subHour();
+
+                    StartScheduleJob::dispatch($schedule->id)
+                        ->delay($date_time_dispatch);
+
+                    break;
+
+                case 'rejected':
+
+                    $notificationService = app(NotificationService::class);
+
+                    $notificationService->create([
+                        'title' => 'Agendamento recusado!',
+
+                        'description' =>
+                        'O diarista não poderá atender. Veja outros profissionais disponíveis.',
+
+                        'origin' => 'schedule',
+
+                        'origin_id' => $schedule->id,
+
+                        'type' =>
+                        NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_REFUSED->value,
+
+                        'user_id' => $schedule->client->user_id,
+                    ]);
+
+                    break;
+            }
+
+
+
+
+
+            DB::commit();
+
+            return $schedule->fresh(['client.user', 'provider.user', 'address']);
+        } catch (\Exception $e) {
+            DB::rollBack();
+            Log::error('Erro ao atualizar status do agendamento: ' . $e->getMessage());
+            throw new \Exception('Não foi possível atualizar o status do agendamento.');
+        }
+    }
+
     public function getClientProviderBlocks(int $clientId, int $providerId): array
     {
         $today = Carbon::today()->format('Y-m-d');
@@ -265,185 +559,6 @@ class ScheduleService
         }
     }
 
-    public function updateStatus($id, string $status)
-    {
-        try {
-            DB::beginTransaction();
-
-            $schedule = Schedule::findOrFail($id);
-
-            $allowedTransitions = [
-                'pending'   => ['accepted', 'rejected'],
-                'accepted'  => ['paid', 'cancelled'],
-                'paid'      => ['cancelled', 'started'],
-                'started'   => ['finished'],
-                'rejected'  => [],
-                'cancelled' => [],
-                'finished'  => [],
-            ];
-
-            $currentStatus = $schedule->status;
-
-            if (! isset($allowedTransitions[$currentStatus])) {
-                throw new \Exception('Status atual inválido.');
-            }
-
-            if (! in_array($status, $allowedTransitions[$currentStatus])) {
-                throw new \Exception("Transição de status não permitida: {$currentStatus} → {$status}");
-            }
-
-            $schedule->update(['status' => $status]);
-
-            switch ($status) {
-                case 'pending':
-                    break;
-
-                case 'accepted':
-                    $notificationService = app(NotificationService::class);
-
-                    // CLIENTE
-
-                    $notificationService->create([
-                        'title'       => 'Agendamento aceito!',
-                        'description' => $schedule->provider->user->name. ' aceitou sua solicitação de diária.',
-                        'origin'      => 'schedule',
-                        'origin_id'   => $schedule->id,
-                        'type'        => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_ACCEPTED->value,
-                        'user_id'     => $schedule->client->user_id,
-                    ]);
-
-                    break;
-
-                case 'rejected':
-                    $notificationService = app(NotificationService::class);
-
-                    // CLIENTE
-
-                    $notificationService->create([
-                        'title'       => 'Agendamento recusado!',
-                        'description' => 'O diarista não poderá atender. Veja outros profissionais disponíveis.',
-                        'origin'      => 'schedule',
-                        'origin_id'   => $schedule->id,
-                        'type'        => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_REFUSED->value,
-                        'user_id'     => $schedule->client->user_id,
-                    ]);
-
-                    break;
-
-                case 'paid':
-                    $notificationService = app(NotificationService::class);
-
-                    // PRESTADOR
-
-                    if ($schedule->provider_id) {
-                        $notificationService->create([
-                            'title'       => 'Pagamento confirmado!',
-                            'description' => 'O cliente confirmou o pagamento da diária.',
-                            'origin'      => 'schedule',
-                            'origin_id'   => $schedule->id,
-                            'type'        => NotificationTypeEnum::SCHEDULE_PROVIDER_START->value,
-                            'user_id'     => $schedule->provider->user_id,
-                        ]);
-                    }
-
-                    $date_cleaned = Carbon::parse($schedule->date)
-                        ->format('Y-m-d');
-
-                    $date_time_dispatch = Carbon::parse(
-                        $date_cleaned.' '.$schedule->start_time
-                    )->subHour();
-
-                    StartScheduleJob::dispatch($schedule->id)
-                        ->delay($date_time_dispatch);
-
-                    break;
-
-                case 'cancelled':
-                    $notificationService = app(NotificationService::class);
-
-                    switch (Auth::user()->type) {
-                        case 'client':
-                            // PRESTADOR
-
-                            if ($schedule->provider_id) {
-
-                                $notificationService->create([
-                                    'title'       => 'Agendamento cancelado!',
-                                    'description' => 'O cliente cancelou a diária.',
-                                    'origin'      => 'schedule',
-                                    'origin_id'   => $schedule->id,
-                                    'type'        => NotificationTypeEnum::SCHEDULE_PROVIDER_CLIENT_CANCELLED->value,
-                                    'user_id'     => $schedule->provider->user_id,
-                                ]);
-                            }
-
-                            break;
-
-                        case 'provider':
-                            // CLIENTE
-
-                            $notificationService->create([
-                                'title'       => 'Agendamento cancelado!',
-                                'description' => $schedule->provider->user->name. ' cancelou a diária.',
-                                'origin'      => 'schedule',
-                                'origin_id'   => $schedule->id,
-                                'type'        => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_CANCELLED->value,
-                                'user_id'     => $schedule->client->user_id,
-                            ]);
-
-                            break;
-
-                        default:
-                            break;
-                    }
-
-                    break;
-
-                case 'started':
-                    $notificationService = app(NotificationService::class);
-
-                    // CLIENTE
-
-                    $notificationService->create([
-                        'title'       => 'Diarista a caminho!',
-                        'description' => 'Informe o código '. $schedule->code. ' para confirmar a chegada da diarista e liberar o início do serviço.',
-                        'origin'      => 'schedule',
-                        'origin_id'   => $schedule->id,
-                        'type'        => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_COMING->value,
-                        'user_id'     => $schedule->client->user_id,
-                    ]);
-
-                    break;
-
-                case 'finished':
-                    $notificationService = app(NotificationService::class);
-
-                    // CLIENTE
-
-                    $notificationService->create([
-                        'title'       => 'Diária finalizada!',
-                        'description' => 'Avalie o serviço feito pelo diarista e conte-nos como foi sua experiência.',
-                        'origin'      => 'schedule',
-                        'origin_id'   => $schedule->id,
-                        'type'        => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_FINISHED->value,
-                        'user_id'     => $schedule->client->user_id,
-                    ]);
-
-                    break;
-            }
-
-            DB::commit();
-
-            return $schedule->fresh(['client.user', 'provider.user', 'address']);
-        } catch (\Exception $e) {
-            DB::rollBack();
-
-            Log::error('Erro ao atualizar status do agendamento: '.$e->getMessage());
-
-            throw new \Exception('Não foi possível atualizar o status do agendamento.');
-        }
-    }
-
     //
 
     private function calculateAmount(Provider $provider, string $periodType): float