Ver código fonte

ajustes agendamento, somente parceiro/admin seta data hora + notificacao para o associado

Gustavo Zanatta 5 horas atrás
pai
commit
e066d65a3f

+ 19 - 5
app/Http/Controllers/AppointmentController.php

@@ -2,9 +2,11 @@
 
 namespace App\Http\Controllers;
 
+use App\Http\Requests\AppointmentApproveRequest;
 use App\Http\Requests\AppointmentRequest;
 use App\Http\Resources\AppointmentResource;
 use App\Services\AppointmentService;
+use App\Enums\AppointmentStatusEnum;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
@@ -33,7 +35,19 @@ class AppointmentController extends Controller
 
     public function store(AppointmentRequest $request): JsonResponse
     {
-        $item = $this->service->create($request->validated());
+        $data = $request->validated();
+        $creatingForOther = isset($data['user_id']) && (int) $data['user_id'] !== Auth::id();
+
+        if ($creatingForOther) {
+            $data['status'] = AppointmentStatusEnum::CONFIRMADO;
+        }
+
+        $item = $this->service->create($data);
+
+        if ($creatingForOther) {
+            $this->service->notifyCreation($item);
+        }
+
         return $this->successResponse(
             payload: new AppointmentResource($item),
             message: __('messages.created'),
@@ -94,9 +108,9 @@ class AppointmentController extends Controller
         ]);
     }
 
-    public function approve(int $id): JsonResponse
+    public function approve(AppointmentApproveRequest $request, int $id): JsonResponse
     {
-        $item = $this->service->approve($id);
+        $item = $this->service->approve($id, $request->date, $request->time);
         return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
     }
 
@@ -106,9 +120,9 @@ class AppointmentController extends Controller
         return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
     }
 
-    public function approveByPartner(int $id): JsonResponse
+    public function approveByPartner(AppointmentApproveRequest $request, int $id): JsonResponse
     {
-        $item = $this->service->approveByPartner($id, Auth::id());
+        $item = $this->service->approveByPartner($id, Auth::id(), $request->date, $request->time);
         if (!$item) return $this->errorResponse(message: __('messages.not_found'), code: 404);
         return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
     }

+ 16 - 0
app/Http/Requests/AppointmentApproveRequest.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class AppointmentApproveRequest extends FormRequest
+{
+    public function rules(): array
+    {
+        return [
+            'date' => 'required|date',
+            'time' => 'required|date_format:H:i',
+        ];
+    }
+}

+ 0 - 2
app/Http/Requests/AppointmentRequest.php

@@ -24,8 +24,6 @@ class AppointmentRequest extends FormRequest
             $rules['user_id']                      = 'required|integer|exists:users,id';
             $rules['partner_agreement_id']         = 'required|integer|exists:partner_agreements,id';
             $rules['partner_agreement_service_id'] = 'required|integer|exists:partner_agreement_services,id';
-            $rules['date']                         = 'required|date';
-            $rules['time']                         = 'required|date_format:H:i';
         }
 
         return $rules;

+ 59 - 4
app/Services/AppointmentService.php

@@ -3,13 +3,16 @@
 namespace App\Services;
 
 use App\Enums\AppointmentStatusEnum;
+use App\Enums\NotificationRecipientEnum;
 use App\Models\Appointment;
+use Carbon\Carbon;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Pagination\LengthAwarePaginator;
 use Illuminate\Support\Str;
 
 class AppointmentService
 {
+    public function __construct(protected NotificationService $notificationService) {}
     public function getAll(): Collection
     {
         return Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])
@@ -46,6 +49,22 @@ class AppointmentService
         return Appointment::create($data);
     }
 
+    public function notifyCreation(Appointment $model): void
+    {
+        $dateStr = $model->date ? Carbon::parse($model->date)->format('d/m/Y') : null;
+        $message = $dateStr
+            ? "Um agendamento #{$model->order_number} foi criado para você" . ($model->time ? " para {$dateStr} às {$model->time}" : " em {$dateStr}") . "."
+            : "Um agendamento #{$model->order_number} foi criado para você.";
+
+        $this->notificationService->createAutoForUser([
+            'title'     => 'Novo agendamento',
+            'message'   => $message,
+            'recipient' => NotificationRecipientEnum::ASSOCIADO,
+            'source'    => 'appointment',
+            'source_id' => $model->id,
+        ], $model->user_id);
+    }
+
     public function update(int $id, array $data): ?Appointment
     {
         $model = Appointment::find($id);
@@ -103,11 +122,22 @@ class AppointmentService
         return $query->paginate($perPage);
     }
 
-    public function approve(int $id): ?Appointment
+    public function approve(int $id, string $date, string $time): ?Appointment
     {
         $model = Appointment::find($id);
         if (!$model) return null;
-        $model->update(['status' => AppointmentStatusEnum::CONFIRMADO]);
+        $model->update([
+            'status' => AppointmentStatusEnum::CONFIRMADO,
+            'date'   => $date,
+            'time'   => $time,
+        ]);
+        $this->notificationService->createAutoForUser([
+            'title'     => 'Agendamento confirmado',
+            'message'   => "Seu agendamento #{$model->order_number} foi confirmado para " . Carbon::parse($date)->format('d/m/Y') . " às {$time}.",
+            'recipient' => NotificationRecipientEnum::ASSOCIADO,
+            'source'    => 'appointment',
+            'source_id' => $model->id,
+        ], $model->user_id);
         return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
     }
 
@@ -116,14 +146,32 @@ class AppointmentService
         $model = Appointment::find($id);
         if (!$model) return null;
         $model->update(['status' => AppointmentStatusEnum::RECUSADO]);
+        $this->notificationService->createAutoForUser([
+            'title'     => 'Agendamento recusado',
+            'message'   => "Seu agendamento #{$model->order_number} foi recusado.",
+            'recipient' => NotificationRecipientEnum::ASSOCIADO,
+            'source'    => 'appointment',
+            'source_id' => $model->id,
+        ], $model->user_id);
         return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
     }
 
-    public function approveByPartner(int $id, int $userId): ?Appointment
+    public function approveByPartner(int $id, int $userId, string $date, string $time): ?Appointment
     {
         $model = Appointment::whereHas('partnerAgreement', fn($q) => $q->where('user_id', $userId))->find($id);
         if (!$model) return null;
-        $model->update(['status' => AppointmentStatusEnum::CONFIRMADO]);
+        $model->update([
+            'status' => AppointmentStatusEnum::CONFIRMADO,
+            'date'   => $date,
+            'time'   => $time,
+        ]);
+        $this->notificationService->createAutoForUser([
+            'title'     => 'Agendamento confirmado',
+            'message'   => "Seu agendamento #{$model->order_number} foi confirmado para " . Carbon::parse($date)->format('d/m/Y') . " às {$time}.",
+            'recipient' => NotificationRecipientEnum::ASSOCIADO,
+            'source'    => 'appointment',
+            'source_id' => $model->id,
+        ], $model->user_id);
         return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
     }
 
@@ -132,6 +180,13 @@ class AppointmentService
         $model = Appointment::whereHas('partnerAgreement', fn($q) => $q->where('user_id', $userId))->find($id);
         if (!$model) return null;
         $model->update(['status' => AppointmentStatusEnum::RECUSADO]);
+        $this->notificationService->createAutoForUser([
+            'title'     => 'Agendamento recusado',
+            'message'   => "Seu agendamento #{$model->order_number} foi recusado.",
+            'recipient' => NotificationRecipientEnum::ASSOCIADO,
+            'source'    => 'appointment',
+            'source_id' => $model->id,
+        ], $model->user_id);
         return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
     }
 

+ 16 - 0
app/Services/NotificationService.php

@@ -97,6 +97,22 @@ class NotificationService
         return true;
     }
 
+    public function createAutoForUser(array $data, int $userId): Notification
+    {
+        $data['created_by'] = Auth::id();
+        $data['type']       = 'automatica';
+
+        $notification = Notification::create($data);
+
+        NotificationSend::create([
+            'notification_id' => $notification->id,
+            'user_id'         => $userId,
+            'read'            => false,
+        ]);
+
+        return $notification;
+    }
+
     public function delete(int $id): bool
     {
         $model = Notification::find($id);

+ 24 - 0
database/migrations/2026_06_16_000002_make_date_time_nullable_in_appointments_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('appointments', function (Blueprint $table) {
+            $table->date('date')->nullable()->change();
+            $table->time('time')->nullable()->change();
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('appointments', function (Blueprint $table) {
+            $table->date('date')->nullable(false)->change();
+            $table->time('time')->nullable(false)->change();
+        });
+    }
+};