Ver Fonte

Merge branch 'fix/diaria-kay-correções-backend' of Softpar/sfp_api_laravel_diarista into development

zntt há 1 semana atrás
pai
commit
a03e443e76

+ 55 - 0
app/Notifications/Push/Cliente/Agendamento/PrestadorCancelouPush.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Notifications\Push\Cliente\Agendamento;
+
+use App\Enums\PushNotificationCategoryEnum;
+use App\Enums\PushNotificationTargetEnum;
+use App\Notifications\Push\BasePushNotification;
+use Illuminate\Database\Eloquent\Collection;
+
+class PrestadorCancelouPush extends BasePushNotification
+{
+    public function __construct(
+        private readonly string $providerName,
+    ) {}
+
+    public function label(): string
+    {
+        return 'provider_cancelled_schedule';
+    }
+
+    public function title(): string
+    {
+        return 'Agendamento cancelado!';
+    }
+
+    public function body(): string
+    {
+        return "{$this->providerName} cancelou seu agendamento.";
+    }
+
+    public function target(): PushNotificationTargetEnum
+    {
+        return PushNotificationTargetEnum::CLIENTE;
+    }
+
+    public function category(): PushNotificationCategoryEnum
+    {
+        return PushNotificationCategoryEnum::AGENDA;
+    }
+
+    public function eligibleUsers(): Collection
+    {
+        return new Collection();
+    }
+
+    public function notificationCooldownDays(): int
+    {
+        return 0;
+    }
+
+    public function categoryCooldownDays(): int
+    {
+        return 0;
+    }
+}

+ 55 - 0
app/Notifications/Push/Cliente/Agendamento/PrestadorRecusouPush.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Notifications\Push\Cliente\Agendamento;
+
+use App\Enums\PushNotificationCategoryEnum;
+use App\Enums\PushNotificationTargetEnum;
+use App\Notifications\Push\BasePushNotification;
+use Illuminate\Database\Eloquent\Collection;
+
+class PrestadorRecusouPush extends BasePushNotification
+{
+    public function __construct(
+        private readonly string $providerName,
+    ) {}
+
+    public function label(): string
+    {
+        return 'client_provider_refused';
+    }
+
+    public function title(): string
+    {
+        return 'Agendamento recusado';
+    }
+
+    public function body(): string
+    {
+        return "{$this->providerName} recusou seu agendamento.";
+    }
+
+    public function target(): PushNotificationTargetEnum
+    {
+        return PushNotificationTargetEnum::CLIENTE;
+    }
+
+    public function category(): PushNotificationCategoryEnum
+    {
+        return PushNotificationCategoryEnum::AGENDA;
+    }
+
+    public function eligibleUsers(): Collection
+    {
+        return new Collection();
+    }
+
+    public function notificationCooldownDays(): int
+    {
+        return 0;
+    }
+
+    public function categoryCooldownDays(): int
+    {
+        return 0;
+    }
+}

+ 55 - 0
app/Notifications/Push/Prestador/Agendamento/ClienteAceitouPush.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Notifications\Push\Prestador\Agendamento;
+
+use App\Enums\PushNotificationCategoryEnum;
+use App\Enums\PushNotificationTargetEnum;
+use App\Notifications\Push\BasePushNotification;
+use Illuminate\Database\Eloquent\Collection;
+
+class ClienteAceitouPush extends BasePushNotification
+{
+    public function __construct(
+        private readonly string $clientName,
+    ) {}
+
+    public function label(): string
+    {
+        return 'provider_client_accepted';
+    }
+
+    public function title(): string
+    {
+        return 'Agendamento confirmado!';
+    }
+
+    public function body(): string
+    {
+        return "{$this->clientName} aceitou sua proposta de agendamento.";
+    }
+
+    public function target(): PushNotificationTargetEnum
+    {
+        return PushNotificationTargetEnum::PRESTADOR;
+    }
+
+    public function category(): PushNotificationCategoryEnum
+    {
+        return PushNotificationCategoryEnum::AGENDA;
+    }
+
+    public function eligibleUsers(): Collection
+    {
+        return new Collection();
+    }
+
+    public function notificationCooldownDays(): int
+    {
+        return 0;
+    }
+
+    public function categoryCooldownDays(): int
+    {
+        return 0;
+    }
+}

+ 55 - 0
app/Notifications/Push/Prestador/Agendamento/ClienteCancelouPush.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Notifications\Push\Prestador\Agendamento;
+
+use App\Enums\PushNotificationCategoryEnum;
+use App\Enums\PushNotificationTargetEnum;
+use App\Notifications\Push\BasePushNotification;
+use Illuminate\Database\Eloquent\Collection;
+
+class ClienteCancelouPush extends BasePushNotification
+{
+    public function __construct(
+        private readonly string $clientName,
+    ) {}
+
+    public function label(): string
+    {
+        return 'provider_client_cancelled';
+    }
+
+    public function title(): string
+    {
+        return 'Agendamento cancelado!';
+    }
+
+    public function body(): string
+    {
+        return "{$this->clientName} cancelou seu agendamento.";
+    }
+
+    public function target(): PushNotificationTargetEnum
+    {
+        return PushNotificationTargetEnum::PRESTADOR;
+    }
+
+    public function category(): PushNotificationCategoryEnum
+    {
+        return PushNotificationCategoryEnum::AGENDA;
+    }
+
+    public function eligibleUsers(): Collection
+    {
+        return new Collection();
+    }
+
+    public function notificationCooldownDays(): int
+    {
+        return 0;
+    }
+
+    public function categoryCooldownDays(): int
+    {
+        return 0;
+    }
+}

+ 55 - 0
app/Notifications/Push/Prestador/Agendamento/ClienteRecusouPush.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Notifications\Push\Prestador\Agendamento;
+
+use App\Enums\PushNotificationCategoryEnum;
+use App\Enums\PushNotificationTargetEnum;
+use App\Notifications\Push\BasePushNotification;
+use Illuminate\Database\Eloquent\Collection;
+
+class ClienteRecusouPush extends BasePushNotification
+{
+    public function __construct(
+        private readonly string $clientName,
+    ) {}
+
+    public function label(): string
+    {
+        return 'provider_client_refused';
+    }
+
+    public function title(): string
+    {
+        return 'Proposta recusada!';
+    }
+
+    public function body(): string
+    {
+        return "{$this->clientName} recusou sua proposta de agendamento.";
+    }
+
+    public function target(): PushNotificationTargetEnum
+    {
+        return PushNotificationTargetEnum::PRESTADOR;
+    }
+
+    public function category(): PushNotificationCategoryEnum
+    {
+        return PushNotificationCategoryEnum::AGENDA;
+    }
+
+    public function eligibleUsers(): Collection
+    {
+        return new Collection();
+    }
+
+    public function notificationCooldownDays(): int
+    {
+        return 0;
+    }
+
+    public function categoryCooldownDays(): int
+    {
+        return 0;
+    }
+}

+ 55 - 0
app/Notifications/Push/Prestador/Pagamento/ClienteEfetuouPagamentoPush.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Notifications\Push\Prestador\Pagamento;
+
+use App\Enums\PushNotificationCategoryEnum;
+use App\Enums\PushNotificationTargetEnum;
+use App\Notifications\Push\BasePushNotification;
+use Illuminate\Database\Eloquent\Collection;
+
+class ClienteEfetuouPagamentoPush extends BasePushNotification
+{
+    public function __construct(
+        private readonly string $clientName,
+    ) {}
+
+    public function label(): string
+    {
+        return 'provider_client_payment_completed';
+    }
+
+    public function title(): string
+    {
+        return 'Pagamento realizado!';
+    }
+
+    public function body(): string
+    {
+        return "{$this->clientName} efetuou o pagamento do serviço.";
+    }
+
+    public function target(): PushNotificationTargetEnum
+    {
+        return PushNotificationTargetEnum::PRESTADOR;
+    }
+
+    public function category(): PushNotificationCategoryEnum
+    {
+        return PushNotificationCategoryEnum::AGENDA;
+    }
+
+    public function eligibleUsers(): Collection
+    {
+        return new Collection();
+    }
+
+    public function notificationCooldownDays(): int
+    {
+        return 0;
+    }
+
+    public function categoryCooldownDays(): int
+    {
+        return 0;
+    }
+}

+ 67 - 13
app/Services/CustomScheduleService.php

@@ -12,10 +12,13 @@ use App\Models\ScheduleProposal;
 use App\Models\ScheduleRefuse;
 use App\Models\ServicePackage;
 use App\Notifications\Push\Cliente\Agendamento\PrestadorAceitouPush;
+use App\Notifications\Push\Cliente\Agendamento\PrestadorRecusouPush;
+use App\Notifications\Push\Prestador\Agendamento\ClienteRecusouPush;
+use App\Notifications\Push\Prestador\Agendamento\ClienteAceitouPush;
+use App\Services\PushNotificationService;
 use App\Rules\ScheduleBusinessRules;
 use App\Services\NotificationService;
 use App\Services\DistanceService;
-use App\Services\PushNotificationService;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
@@ -120,7 +123,7 @@ class CustomScheduleService
         } catch (\Exception $e) {
             DB::rollBack();
 
-            Log::error('Erro ao criar agendamento personalizado: '.$e->getMessage());
+            Log::error('Erro ao criar agendamento personalizado: ' . $e->getMessage());
 
             throw $e;
         }
@@ -215,7 +218,7 @@ class CustomScheduleService
         } catch (\Exception $e) {
             DB::rollBack();
 
-            Log::error('Erro ao atualizar agendamento personalizado: '.$e->getMessage());
+            Log::error('Erro ao atualizar agendamento personalizado: ' . $e->getMessage());
 
             throw $e;
         }
@@ -241,7 +244,7 @@ class CustomScheduleService
         } catch (\Exception $e) {
             DB::rollBack();
 
-            Log::error('Erro ao excluir agendamento personalizado: '.$e->getMessage());
+            Log::error('Erro ao excluir agendamento personalizado: ' . $e->getMessage());
 
             throw $e;
         }
@@ -495,9 +498,7 @@ class CustomScheduleService
 
     public function refuseOpportunity($scheduleId, $providerId)
     {
-
         $schedule = Schedule::with(['client.user'])->findOrFail($scheduleId);
-
         $provider = Provider::with(['user'])->findOrFail($providerId);
 
         $schedule_refuse = ScheduleRefuse::create([
@@ -508,14 +509,35 @@ class CustomScheduleService
         $notificationService = app(NotificationService::class);
 
         $notificationService->create([
-            'title'       => __('notifications.opportunity_refused_title'),
-            'description' => __('notifications.opportunity_refused_description', ['provider' => $provider->user->name]),
-            'origin'      => 'schedule',
-            'origin_id'   => $scheduleId,
-            'type'        => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_REFUSED->value,
-            'user_id'     => $schedule->client->user_id,
+            'title' => __('notifications.opportunity_refused_title'),
+            'description' => __('notifications.opportunity_refused_description', [
+                'provider' => $provider->user->name,
+            ]),
+            'origin' => 'schedule',
+            'origin_id' => $scheduleId,
+            'type' => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_REFUSED->value,
+            'user_id' => $schedule->client->user_id,
         ]);
 
+        // Push notification
+        if ($schedule->client?->user) {
+            try {
+                app(PushNotificationService::class)->sendToUser(
+                    $schedule->client->user,
+                    new PrestadorRecusouPush(
+                        $provider->user->name
+                    )
+                );
+            } catch (\Throwable $exception) {
+                Log::error('Falha ao enviar push de recusa da oportunidade', [
+                    'schedule_id' => $schedule->id,
+                    'provider_id' => $providerId,
+                    'user_id' => $schedule->client->user->id,
+                    'error' => $exception->getMessage(),
+                ]);
+            }
+        }
+
         return $schedule_refuse;
     }
 
@@ -556,6 +578,20 @@ class CustomScheduleService
                 'user_id'     => $provider->user_id,
             ]);
 
+            try {
+                app(PushNotificationService::class)->sendToUser(
+                    $provider->user,
+                    new ClienteAceitouPush($schedule->client->user->name)
+                );
+            } catch (\Throwable $exception) {
+                Log::error('Falha ao enviar push de cliente aceitou proposta', [
+                    'schedule_id' => $schedule->id,
+                    'provider_id' => $provider->id,
+                    'error' => $exception->getMessage(),
+                ]);
+            }
+
+
             app(ScheduleService::class)->updateStatus($schedule->id, 'accepted');
 
             ScheduleProposal::where('schedule_id', $schedule->id)
@@ -616,7 +652,25 @@ class CustomScheduleService
                 'type'        => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_REFUSED->value,
                 'user_id'     => $proposal->provider->user_id,
             ]);
-
+            // Push notification
+            if ($proposal->provider?->user) {
+                try {
+                    app(PushNotificationService::class)->sendToUser(
+                        $proposal->provider->user,
+                        new ClienteRecusouPush(
+                            $proposal->schedule?->client?->user?->name
+                        )
+                    );
+                } catch (\Throwable $exception) {
+                    Log::error('Falha ao enviar push de recusa da proposta', [
+                        'proposal_id' => $proposal->id,
+                        'schedule_id' => $proposal->schedule_id,
+                        'provider_id' => $proposal->provider_id,
+                        'user_id'     => $proposal->provider->user->id,
+                        'error'       => $exception->getMessage(),
+                    ]);
+                }
+            }
 
             $proposal->delete();
 

+ 161 - 7
app/Services/ScheduleService.php

@@ -14,6 +14,11 @@ use App\Rules\ScheduleBusinessRules;
 use App\Services\NotificationService;
 use App\Services\PushNotificationService;
 use App\Notifications\Push\Cliente\Agendamento\PrestadorAceitouPush;
+use App\Notifications\Push\Cliente\Agendamento\PrestadorRecusouPush;
+use App\Notifications\Push\Prestador\Agendamento\ClienteAceitouPush;
+use App\Notifications\Push\Prestador\Pagamento\ClienteEfetuouPagamentoPush;
+use App\Notifications\Push\Cliente\Agendamento\PrestadorCancelouPush;
+use App\Notifications\Push\Prestador\Agendamento\ClienteCancelouPush;
 use App\Notifications\Push\Prestador\Agendamento\NewPushRequest;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\Auth;
@@ -219,6 +224,8 @@ class ScheduleService
                                 ]);
                             }
 
+                            $this->sendClientAcceptedPush($schedule);
+
                             break;
 
                         default:
@@ -240,6 +247,7 @@ class ScheduleService
                                 'type'        => NotificationTypeEnum::SCHEDULE_PROVIDER_CLIENT_CANCELLED->value,
                                 'user_id'     => $schedule->provider->user_id,
                             ]);
+                            $this->sendProviderCancelledPush($schedule);
 
                             break;
 
@@ -252,6 +260,7 @@ class ScheduleService
                                 'type'        => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_CANCELLED->value,
                                 'user_id'     => $schedule->client->user_id,
                             ]);
+                            $this->sendClientCancelledPush($schedule);
 
                             break;
 
@@ -319,7 +328,7 @@ class ScheduleService
                                     'user_id'     => $schedule->provider->user_id,
                                 ]);
                             }
-
+                            $this->sendClientPaymentPush($schedule);
                             break;
 
                         default:
@@ -350,6 +359,8 @@ class ScheduleService
                         'user_id'     => $schedule->client->user_id,
                     ]);
 
+                    $this->sendProviderRefusedPush($schedule);
+
                     break;
             }
 
@@ -550,26 +561,28 @@ class ScheduleService
             $siblingSchedules = $package->items->pluck('schedule')->filter();
 
             $siblingSchedules
-                ->filter(fn (Schedule $sibling) => $sibling->id !== $schedule->id
+                ->filter(fn(Schedule $sibling) => $sibling->id !== $schedule->id
                     && in_array($sibling->status, ['pending', 'accepted', 'paid'], true))
-                ->each(fn (Schedule $sibling) => $sibling->update([
+                ->each(fn(Schedule $sibling) => $sibling->update([
                     'status'       => 'cancelled',
                     'cancel_text'  => $cancelText,
                     'cancelled_by' => $cancelledBy,
                 ]));
 
             $hasRealizedSchedule = $siblingSchedules->contains(
-                fn (Schedule $sibling) => in_array($sibling->status, ['started', 'finished'], true),
+                fn(Schedule $sibling) => in_array($sibling->status, ['started', 'finished'], true),
             );
 
-            if ($package->status === ServicePackageStatusEnum::OPEN
-                || ($package->status === ServicePackageStatusEnum::PAID && ! $hasRealizedSchedule)) {
+            if (
+                $package->status === ServicePackageStatusEnum::OPEN
+                || ($package->status === ServicePackageStatusEnum::PAID && ! $hasRealizedSchedule)
+            ) {
                 $package->update(['status' => ServicePackageStatusEnum::CANCELLED->value]);
             }
         }
     }
 
-    //
+    //Notificações por push do sistema
 
     private function sendProviderAcceptedPush(Schedule $schedule): void
     {
@@ -597,6 +610,147 @@ class ScheduleService
         }
     }
 
+    private function sendProviderRefusedPush(Schedule $schedule): void
+    {
+        $user = $schedule->client->user;
+
+        if (! $user) {
+            Log::warning('Push de recusa ignorada: cliente sem usuário', [
+                'schedule_id' => $schedule->id,
+            ]);
+
+            return;
+        }
+
+        try {
+            app(PushNotificationService::class)->sendToUser(
+                $user,
+                new PrestadorRecusouPush(
+                    $schedule->provider->user->name
+                )
+            );
+        } catch (\Throwable $exception) {
+            Log::error('Falha ao enviar push de recusa do prestador', [
+                'schedule_id' => $schedule->id,
+                'user_id'     => $user->id,
+                'error'       => $exception->getMessage(),
+            ]);
+        }
+    }
+
+    private function sendClientAcceptedPush(Schedule $schedule): void
+    {
+        $user = $schedule->provider?->user;
+
+        if (! $user) {
+            Log::warning('Push de aceite do cliente ignorado: prestador sem usuário', [
+                'schedule_id' => $schedule->id,
+            ]);
+
+            return;
+        }
+
+        try {
+            app(PushNotificationService::class)->sendToUser(
+                $user,
+                new ClienteAceitouPush(
+                    $schedule->client->user->name
+                )
+            );
+        } catch (\Throwable $exception) {
+            Log::error('Falha ao enviar push de aceite do cliente', [
+                'schedule_id' => $schedule->id,
+                'user_id' => $user->id,
+                'error' => $exception->getMessage(),
+            ]);
+        }
+    }
+
+    private function sendClientPaymentPush(Schedule $schedule): void
+    {
+        $user = $schedule->provider?->user;
+
+        if (! $user) {
+            Log::warning('Push de pagamento ignorado: prestador sem usuário', [
+                'schedule_id' => $schedule->id,
+            ]);
+
+            return;
+        }
+
+        try {
+            app(PushNotificationService::class)->sendToUser(
+                $user,
+                new ClienteEfetuouPagamentoPush(
+                    $schedule->client?->user?->name ?? 'Cliente'
+                )
+            );
+        } catch (\Throwable $exception) {
+            Log::error('Falha ao enviar push de pagamento ao prestador', [
+                'schedule_id' => $schedule->id,
+                'provider_id' => $schedule->provider_id,
+                'user_id' => $user->id,
+                'error' => $exception->getMessage(),
+            ]);
+        }
+    }
+
+    private function sendClientCancelledPush(Schedule $schedule): void
+    {
+        $user = $schedule->provider->user;
+
+        if (! $user) {
+            Log::warning('Push de cancelamento ignorado: prestador sem usuário', [
+                'schedule_id' => $schedule->id,
+            ]);
+
+            return;
+        }
+
+        try {
+            app(PushNotificationService::class)->sendToUser(
+                $user,
+                new ClienteCancelouPush(
+                    $schedule->client->user->name
+                )
+            );
+        } catch (\Throwable $exception) {
+            Log::error('Falha ao enviar push de cancelamento pelo cliente', [
+                'schedule_id' => $schedule->id,
+                'user_id'     => $user->id,
+                'error'       => $exception->getMessage(),
+            ]);
+        }
+    }
+
+    private function sendProviderCancelledPush(Schedule $schedule): void
+    {
+        $user = $schedule->client->user;
+
+        if (! $user) {
+            Log::warning('Push de cancelamento ignorado: cliente sem usuário', [
+                'schedule_id' => $schedule->id,
+            ]);
+
+            return;
+        }
+
+        try {
+            app(PushNotificationService::class)->sendToUser(
+                $user,
+                new PrestadorCancelouPush(
+                    $schedule->provider->user->name
+                )
+            );
+        } catch (\Throwable $exception) {
+            Log::error('Falha ao enviar push de cancelamento pelo prestador', [
+                'schedule_id' => $schedule->id,
+                'user_id'     => $user->id,
+                'error'       => $exception->getMessage(),
+            ]);
+        }
+    }
+
     private function calculateAmount(Provider $provider, string $periodType): float
     {
         $hourlyRates = [