Browse Source

push notifications para prestador apos 20 min do inicio + push para cliente quando prestador aceita agendamento ou envia proposta pra sob medida

Gustavo Zanatta 1 day ago
parent
commit
0f8da47f91

+ 6 - 4
app/Models/Schedule.php

@@ -82,16 +82,18 @@ class Schedule extends Model
         'total_amount',
         'code',
         'code_verified',
+        'code_reminder_sent_at',
         'offers_meal',
         'cancel_text',
         'cancelled_by',
     ];
 
     protected $casts = [
-        'date'          => 'date',
-        'code_verified' => 'boolean',
-        'total_amount'  => 'decimal:2',
-        'offers_meal'   => 'boolean',
+        'date'                   => 'date',
+        'code_verified'          => 'boolean',
+        'code_reminder_sent_at'  => 'datetime',
+        'total_amount'           => 'decimal:2',
+        'offers_meal'            => 'boolean',
     ];
 
     public function client()

+ 64 - 0
app/Notifications/Push/Cliente/Agendamento/PrestadorAceitouPush.php

@@ -0,0 +1,64 @@
+<?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;
+
+/**
+ * Notificação enviada ao cliente quando um prestador aceita seu agendamento
+ * (agendamento padrão) ou envia uma proposta para um pedido sob medida.
+ */
+class PrestadorAceitouPush extends BasePushNotification
+{
+    public function __construct(
+        private readonly string $providerName,
+        private readonly bool $isProposal = false,
+    ) {}
+
+    public function label(): string
+    {
+        return 'client_provider_accepted';
+    }
+
+    public function title(): string
+    {
+        return $this->isProposal
+            ? 'Nova proposta recebida'
+            : 'Prestador confirmado! 🎉';
+    }
+
+    public function body(): string
+    {
+        return $this->isProposal
+            ? "{$this->providerName} enviou uma proposta para o seu pedido sob medida."
+            : "{$this->providerName} aceitou 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;
+    }
+}

+ 59 - 0
app/Notifications/Push/Prestador/Agendamento/CodigoNaoPreenchidoPush.php

@@ -0,0 +1,59 @@
+<?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;
+
+/**
+ * Lembrete enviado ao prestador quando um atendimento já iniciou
+ * há 20 minutos e o código de confirmação ainda não foi preenchido.
+ */
+class CodigoNaoPreenchidoPush extends BasePushNotification
+{
+    public function __construct(
+        private readonly string $clientName,
+    ) {}
+
+    public function label(): string
+    {
+        return 'provider_code_reminder';
+    }
+
+    public function title(): string
+    {
+        return 'Confirme o código do atendimento';
+    }
+
+    public function body(): string
+    {
+        return "Não esqueça de confirmar o código informado por {$this->clientName} para iniciar o registro do serviço.";
+    }
+
+    public function target(): PushNotificationTargetEnum
+    {
+        return PushNotificationTargetEnum::PRESTADOR;
+    }
+
+    public function category(): PushNotificationCategoryEnum
+    {
+        return PushNotificationCategoryEnum::TRANSACIONAL;
+    }
+
+    public function eligibleUsers(): Collection
+    {
+        return new Collection();
+    }
+
+    public function notificationCooldownDays(): int
+    {
+        return 0;
+    }
+
+    public function categoryCooldownDays(): int
+    {
+        return 0;
+    }
+}

+ 30 - 0
app/Services/CustomScheduleService.php

@@ -11,8 +11,10 @@ use App\Models\Schedule;
 use App\Models\ScheduleProposal;
 use App\Models\ScheduleRefuse;
 use App\Models\ServicePackage;
+use App\Notifications\Push\Cliente\Agendamento\PrestadorAceitouPush;
 use App\Rules\ScheduleBusinessRules;
 use App\Services\NotificationService;
+use App\Services\PushNotificationService;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
@@ -414,12 +416,40 @@ class CustomScheduleService
             'user_id'     => $schedule->client->user_id,
         ]);
 
+        $this->sendProposalReceivedPush($schedule, $provider->user->name);
+
         return ScheduleProposal::create([
             'schedule_id' => $scheduleId,
             'provider_id' => $providerId,
         ]);
     }
 
+    private function sendProposalReceivedPush(Schedule $schedule, string $providerName): void
+    {
+        $user = $schedule->client->user;
+
+        if (! $user) {
+            Log::warning('Push de proposta ignorada: cliente sem usuário', [
+                'schedule_id' => $schedule->id,
+            ]);
+
+            return;
+        }
+
+        try {
+            app(PushNotificationService::class)->sendToUser(
+                $user,
+                new PrestadorAceitouPush($providerName, isProposal: true)
+            );
+        } catch (\Throwable $exception) {
+            Log::error('Falha ao enviar push de nova proposta sob medida', [
+                'schedule_id' => $schedule->id,
+                'user_id'     => $user->id,
+                'error'       => $exception->getMessage(),
+            ]);
+        }
+    }
+
     public function refuseOpportunity($scheduleId, $providerId)
     {
 

+ 29 - 0
app/Services/ScheduleService.php

@@ -13,6 +13,7 @@ use App\Models\ServicePackage;
 use App\Rules\ScheduleBusinessRules;
 use App\Services\NotificationService;
 use App\Services\PushNotificationService;
+use App\Notifications\Push\Cliente\Agendamento\PrestadorAceitouPush;
 use App\Notifications\Push\Prestador\Agendamento\NewPushRequest;
 use Carbon\Carbon;
 use Illuminate\Support\Facades\Auth;
@@ -202,6 +203,8 @@ class ScheduleService
                                 'user_id'     => $schedule->client->user_id,
                             ]);
 
+                            $this->sendProviderAcceptedPush($schedule);
+
                             break;
 
                         case UserTypeEnum::CLIENT:
@@ -568,6 +571,32 @@ class ScheduleService
 
     //
 
+    private function sendProviderAcceptedPush(Schedule $schedule): void
+    {
+        $user = $schedule->client->user;
+
+        if (! $user) {
+            Log::warning('Push de aceite ignorada: cliente sem usuário', [
+                'schedule_id' => $schedule->id,
+            ]);
+
+            return;
+        }
+
+        try {
+            app(PushNotificationService::class)->sendToUser(
+                $user,
+                new PrestadorAceitouPush($schedule->provider->user->name)
+            );
+        } catch (\Throwable $exception) {
+            Log::error('Falha ao enviar push de aceite do prestador', [
+                'schedule_id' => $schedule->id,
+                'user_id'     => $user->id,
+                'error'       => $exception->getMessage(),
+            ]);
+        }
+    }
+
     private function calculateAmount(Provider $provider, string $periodType): float
     {
         $hourlyRates = [

+ 22 - 0
database/migrations/2026_08_28_141841_add_code_reminder_sent_at_to_schedules_table.php

@@ -0,0 +1,22 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::table('schedules', function (Blueprint $table) {
+            $table->timestamp('code_reminder_sent_at')->nullable();
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('schedules', function (Blueprint $table) {
+            $table->dropColumn('code_reminder_sent_at');
+        });
+    }
+};