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

feat: :sparkles: feat (agendamentos) fluxo cancelamento de um agendamento

foi criado o fluxo de cancelamento de um agendamento por parte do prestador

fase:dev | origin:escopo
Gustavo Zanatta 2 hete
szülő
commit
302b628ea3

+ 19 - 1
app/Http/Controllers/ScheduleController.php

@@ -6,7 +6,7 @@ use App\Http\Requests\ScheduleRequest;
 use App\Http\Resources\ScheduleResource;
 use App\Services\ScheduleService;
 use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Request;
+use Illuminate\Http\Request;
 
 class ScheduleController extends Controller
 {
@@ -102,4 +102,22 @@ class ScheduleController extends Controller
       return $this->errorResponse($e->getMessage(), 422);
     }
   }
+
+  public function cancelWithReason(string $id, Request $request): JsonResponse
+  {
+    try {
+      $validated = $request->validate([
+        'cancel_text' => 'required|string|min:5|max:1000',
+      ]);
+
+      $schedule = $this->scheduleService->cancelWithReason((int) $id, $validated['cancel_text']);
+
+      return $this->successResponse(
+        payload: new ScheduleResource($schedule),
+        message: __("messages.updated"),
+      );
+    } catch (\Exception $e) {
+      return $this->errorResponse($e->getMessage(), 422);
+    }
+  }
 }

+ 2 - 0
app/Models/Schedule.php

@@ -24,6 +24,8 @@ class Schedule extends Model
         'code',
         'code_verified',
         'offers_meal',
+        'cancel_text',
+        'cancelled_by',
     ];
 
     protected $casts = [

+ 3 - 0
app/Services/DashboardService.php

@@ -225,6 +225,7 @@ class DashboardService
         'schedules.period_type',
         'schedules.schedule_type',
         'schedules.address_id',
+        'schedules.status',
         'custom_schedules.offers_meal',
         DB::raw("CASE
           WHEN (now() - schedules.created_at) < INTERVAL '1 day' THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (now() - schedules.created_at)) / 3600), ' hours ago')
@@ -253,6 +254,7 @@ class DashboardService
         'schedules.schedule_type',
         'schedules.status',
         'schedules.code_verified',
+        'schedules.status',
         'custom_schedules.offers_meal',
       )
       ->orderBy('schedules.start_time', 'asc')
@@ -274,6 +276,7 @@ class DashboardService
         'schedules.period_type',
         'schedules.address_id',
         'schedules.schedule_type',
+        'schedules.status',
         'custom_schedules.offers_meal',
       )
       ->orderBy('schedules.date', 'asc')

+ 29 - 0
app/Services/ScheduleService.php

@@ -10,6 +10,7 @@ use App\Models\ProviderBlockedDay;
 use App\Models\ProviderWorkingDay;
 use App\Rules\ScheduleBusinessRules;
 use Carbon\Carbon;
+use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
 
@@ -291,4 +292,32 @@ class ScheduleService
       throw new \Exception("Não foi possível atualizar o status do agendamento.");
     }
   }
+
+  public function cancelWithReason(int $id, string $cancelText)
+  {
+    try {
+      DB::beginTransaction();
+      $schedule = Schedule::findOrFail($id);
+
+      $allowedStatuses = ['accepted', 'paid'];
+      if (!in_array($schedule->status, $allowedStatuses)) {
+        throw new \Exception("Cancelamento não permitido para o status atual: {$schedule->status}");
+      }
+
+      $cancelled_by = Auth::user()->type;
+
+      $schedule->update([
+        'status'      => 'cancelled',
+        'cancel_text' => $cancelText,
+        'cancelled_by' => $cancelled_by,
+      ]);
+
+      DB::commit();
+      return $schedule->fresh(['client.user', 'provider.user', 'address']);
+    } catch (\Exception $e) {
+      DB::rollBack();
+      Log::error("Erro ao cancelar agendamento: " . $e->getMessage());
+      throw new \Exception("Não foi possível cancelar o agendamento.");
+    }
+  }
 }

+ 24 - 0
database/migrations/2026_04_14_000001_add_cancel_text_to_schedules_table.php

@@ -0,0 +1,24 @@
+<?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->text('cancel_text')->nullable()->after('offers_meal');
+            $table->string('cancelled_by')->nullable()->after('cancel_text');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('schedules', function (Blueprint $table) {
+            $table->dropColumn('cancel_text');
+            $table->dropColumn('cancelled_by');
+        });
+    }
+};

+ 1 - 0
routes/authRoutes/schedule.php

@@ -10,4 +10,5 @@ Route::get('/schedule/{id}', [ScheduleController::class, 'show'])->middleware('p
 Route::post('/schedule', [ScheduleController::class, 'store'])->middleware('permission:config.schedule,add');
 Route::put('/schedule/{id}', [ScheduleController::class, 'update'])->middleware('permission:config.schedule,edit');
 Route::patch('/schedule/{id}/status', [ScheduleController::class, 'updateStatus'])->middleware('permission:config.schedule,edit');
+Route::patch('/schedule/{id}/cancel', [ScheduleController::class, 'cancelWithReason'])->middleware('permission:config.schedule,edit');
 Route::delete('/schedule/{id}', [ScheduleController::class, 'destroy'])->middleware('permission:config.schedule,delete');