|
|
@@ -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
|