|
|
@@ -25,15 +25,6 @@ class ScheduleService
|
|
|
->get();
|
|
|
}
|
|
|
|
|
|
- public function getFinished()
|
|
|
- {
|
|
|
- return Schedule::with(['client.user', 'provider.user'])
|
|
|
- ->where('status', 'finished')
|
|
|
- ->orderBy('date', 'desc')
|
|
|
- ->orderBy('start_time', 'desc')
|
|
|
- ->get();
|
|
|
- }
|
|
|
-
|
|
|
public function getById($id)
|
|
|
{
|
|
|
return Schedule::with(['client.user', 'provider.user', 'address'])->findOrFail($id);
|
|
|
@@ -42,13 +33,11 @@ class ScheduleService
|
|
|
public function createSingleOrMultiple(array $baseData, array $schedules)
|
|
|
{
|
|
|
try {
|
|
|
-
|
|
|
DB::beginTransaction();
|
|
|
|
|
|
$createdSchedules = [];
|
|
|
|
|
|
foreach ($schedules as $schedule) {
|
|
|
-
|
|
|
$datasMerged = array_merge($baseData, $schedule);
|
|
|
|
|
|
$this->validateProviderAvailability($datasMerged, null);
|
|
|
@@ -59,23 +48,18 @@ class ScheduleService
|
|
|
|
|
|
$newSchedule = Schedule::create($scheduleData);
|
|
|
|
|
|
- /* NOTIFICAÇÃO PRESTADOR */
|
|
|
- if ($newSchedule->provider_id) {
|
|
|
+ // NOTIFICAÇÃO PRESTADOR
|
|
|
|
|
|
+ if ($newSchedule->provider_id) {
|
|
|
$notificationService = app(NotificationService::class);
|
|
|
|
|
|
$notificationService->create([
|
|
|
- 'title' => 'Nova solicitação de diária!',
|
|
|
-
|
|
|
+ 'title' => 'Nova solicitação de diária!',
|
|
|
'description' => 'Você recebeu uma nova solicitação de diária.',
|
|
|
-
|
|
|
- 'origin' => 'schedule',
|
|
|
-
|
|
|
- 'origin_id' => $newSchedule->id,
|
|
|
-
|
|
|
- 'type' => NotificationTypeEnum::SCHEDULE_PROVIDER_CLIENT_NEW_SOLICITATION->value,
|
|
|
-
|
|
|
- 'user_id' => $newSchedule->provider->user_id,
|
|
|
+ 'origin' => 'schedule',
|
|
|
+ 'origin_id' => $newSchedule->id,
|
|
|
+ 'type' => NotificationTypeEnum::SCHEDULE_PROVIDER_CLIENT_NEW_SOLICITATION->value,
|
|
|
+ 'user_id' => $newSchedule->provider->user_id,
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
@@ -84,7 +68,6 @@ class ScheduleService
|
|
|
|
|
|
DB::commit();
|
|
|
} catch (\Exception $e) {
|
|
|
-
|
|
|
DB::rollBack();
|
|
|
|
|
|
throw new \Exception(__($e->getMessage()));
|
|
|
@@ -100,7 +83,9 @@ class ScheduleService
|
|
|
if (isset($data['provider_id']) || isset($data['period_type'])) {
|
|
|
$providerId = $data['provider_id'] ?? $schedule->provider_id;
|
|
|
$periodType = $data['period_type'] ?? $schedule->period_type;
|
|
|
+
|
|
|
$provider = Provider::findOrFail($providerId);
|
|
|
+
|
|
|
$data['total_amount'] = $this->calculateAmount($provider, $periodType);
|
|
|
}
|
|
|
|
|
|
@@ -124,84 +109,55 @@ class ScheduleService
|
|
|
return $schedule;
|
|
|
}
|
|
|
|
|
|
- private function calculateAmount(Provider $provider, string $periodType): float
|
|
|
- {
|
|
|
- $hourlyRates = [
|
|
|
- '2' => $provider->daily_price_2h ?? 0,
|
|
|
- '4' => $provider->daily_price_4h ?? 0,
|
|
|
- '6' => $provider->daily_price_6h ?? 0,
|
|
|
- '8' => $provider->daily_price_8h ?? 0,
|
|
|
- ];
|
|
|
-
|
|
|
- return $hourlyRates[$periodType] ?? 0;
|
|
|
- }
|
|
|
+ //
|
|
|
|
|
|
- private function validateProviderAvailability(array $data, $excludeScheduleId = null)
|
|
|
+ public function getClientProviderBlocks(int $clientId, int $providerId): array
|
|
|
{
|
|
|
- $provider_id = $data['provider_id'];
|
|
|
- $client_id = $data['client_id'];
|
|
|
-
|
|
|
- $date = Carbon::parse($data['date']);
|
|
|
- $dayOfWeek = $date->dayOfWeek;
|
|
|
- $startTime = $data['start_time'];
|
|
|
- $endTime = $data['end_time'];
|
|
|
- $date_ymd = $date->format('Y-m-d');
|
|
|
- $period = $startTime < '13:00:00' ? 'morning' : 'afternoon';
|
|
|
-
|
|
|
- // bloqueio 2 schedules por semana para o mesmo client e provider
|
|
|
- ScheduleBusinessRules::validateWeeklyScheduleLimit(
|
|
|
- $client_id,
|
|
|
- $provider_id,
|
|
|
- $data['date'],
|
|
|
- $excludeScheduleId
|
|
|
- );
|
|
|
-
|
|
|
- // bloqueio provider trabalha no dia/periodo
|
|
|
- ScheduleBusinessRules::validateWorkingDay(
|
|
|
- $provider_id,
|
|
|
- $dayOfWeek,
|
|
|
- $period
|
|
|
- );
|
|
|
-
|
|
|
- // bloqueio provider tem blockedday para dia/hora
|
|
|
- ScheduleBusinessRules::validateBlockedDay(
|
|
|
- $provider_id,
|
|
|
- $date->format('Y-m-d'),
|
|
|
- $startTime,
|
|
|
- $endTime
|
|
|
- );
|
|
|
+ $today = Carbon::today()->format('Y-m-d');
|
|
|
|
|
|
- // bloqueio provider tem outro agendamento para dia/hora
|
|
|
- ScheduleBusinessRules::validateConflictingSchedule(
|
|
|
- $provider_id,
|
|
|
- $date->format('Y-m-d'),
|
|
|
- $startTime,
|
|
|
- $endTime,
|
|
|
- $excludeScheduleId
|
|
|
- );
|
|
|
+ $schedules = Schedule::where('client_id', $clientId)
|
|
|
+ ->where('provider_id', $providerId)
|
|
|
+ ->whereNotIn('status', self::EXCLUDED_STATUSES)
|
|
|
+ ->whereDate('date', '>=', $today)
|
|
|
+ ->orderBy('date')
|
|
|
+ ->orderBy('start_time')
|
|
|
+ ->get(['id', 'date', 'start_time', 'end_time', 'status']);
|
|
|
|
|
|
- // bloqueio provider tem outra proposta na mesma data
|
|
|
- ScheduleBusinessRules::validateConflictingProposalSameDate(
|
|
|
- $provider_id,
|
|
|
- $date_ymd,
|
|
|
- $startTime,
|
|
|
- $endTime,
|
|
|
- null
|
|
|
- );
|
|
|
+ $existingSchedules = $schedules->map(function ($schedule) {
|
|
|
+ return [
|
|
|
+ 'id' => $schedule->id,
|
|
|
+ 'date' => Carbon::parse($schedule->date)->format('Y-m-d'),
|
|
|
+ 'start_time' => $schedule->start_time,
|
|
|
+ 'end_time' => $schedule->end_time,
|
|
|
+ 'status' => $schedule->status,
|
|
|
+ ];
|
|
|
+ })->values();
|
|
|
|
|
|
- // bloqueio caso o client tenha bloqueado o provider
|
|
|
- ScheduleBusinessRules::validateClientNotBlockedByProvider(
|
|
|
- $client_id,
|
|
|
- $provider_id
|
|
|
- );
|
|
|
+ $fullyBlockedWeeks = $schedules
|
|
|
+ ->groupBy(function ($schedule) {
|
|
|
+ return Carbon::parse($schedule->date)
|
|
|
+ ->startOfWeek(Carbon::SUNDAY)
|
|
|
+ ->format('Y-m-d');
|
|
|
+ })
|
|
|
+ ->filter(function ($weekSchedules) {
|
|
|
+ return $weekSchedules->count() >= 2;
|
|
|
+ })
|
|
|
+ ->keys()
|
|
|
+ ->values();
|
|
|
|
|
|
- // bloqueio caso o provider tenha bloqueado o client
|
|
|
- ScheduleBusinessRules::validateProviderNotBlockedByClient(
|
|
|
- $client_id,
|
|
|
- $provider_id
|
|
|
- );
|
|
|
+ return [
|
|
|
+ 'existing_schedules' => $existingSchedules,
|
|
|
+ 'fully_blocked_weeks' => $fullyBlockedWeeks,
|
|
|
+ ];
|
|
|
+ }
|
|
|
|
|
|
- return true;
|
|
|
+ public function getFinished()
|
|
|
+ {
|
|
|
+ return Schedule::with(['client.user', 'provider.user'])
|
|
|
+ ->where('status', 'finished')
|
|
|
+ ->orderBy('date', 'desc')
|
|
|
+ ->orderBy('start_time', 'desc')
|
|
|
+ ->get();
|
|
|
}
|
|
|
|
|
|
public function getSchedulesDefaultGroupedByClient()
|
|
|
@@ -220,7 +176,8 @@ class ScheduleService
|
|
|
return [
|
|
|
'client_id' => $firstSchedule->client_id,
|
|
|
'client_name' => $firstSchedule->client->user->name ?? 'N/A',
|
|
|
- 'schedules' => $clientSchedules->map(function ($schedule) {
|
|
|
+
|
|
|
+ 'schedules' => $clientSchedules->map(function ($schedule) {
|
|
|
return [
|
|
|
'id' => $schedule->id,
|
|
|
'date' => $schedule->date ? Carbon::parse($schedule->date)->format('d/m/Y') : null,
|
|
|
@@ -234,16 +191,19 @@ class ScheduleService
|
|
|
'client_id' => $schedule->client_id,
|
|
|
'provider_id' => $schedule->provider_id,
|
|
|
'provider_name' => $schedule->provider->user->name ?? 'N/A',
|
|
|
- 'address' => $schedule->address ? [
|
|
|
+
|
|
|
+ 'address' => $schedule->address ? [
|
|
|
'id' => $schedule->address->id,
|
|
|
'address' => $schedule->address->address,
|
|
|
'complement' => $schedule->address->complement,
|
|
|
'zip_code' => $schedule->address->zip_code,
|
|
|
- 'city' => $schedule->address->city->name ?? '',
|
|
|
+ 'city' => $schedule->address->city->name ?? '',
|
|
|
'state' => $schedule->address->city->state->name ?? '',
|
|
|
] : null,
|
|
|
+
|
|
|
'client_name' => $schedule->client->user->name ?? 'N/A',
|
|
|
- 'reviews' => $schedule->reviews->map(function ($review) {
|
|
|
+
|
|
|
+ 'reviews' => $schedule->reviews->map(function ($review) {
|
|
|
return [
|
|
|
'id' => $review->id,
|
|
|
'stars' => $review->stars,
|
|
|
@@ -252,6 +212,7 @@ class ScheduleService
|
|
|
'origin_id' => $review->origin_id,
|
|
|
'created_at' => Carbon::parse($review->created_at)->format('Y-m-d H:i'),
|
|
|
'updated_at' => Carbon::parse($review->updated_at)->format('Y-m-d H:i'),
|
|
|
+
|
|
|
'improvements' => $review->reviewsImprovements->map(function ($ri) {
|
|
|
return [
|
|
|
'id' => $ri->id,
|
|
|
@@ -269,10 +230,46 @@ class ScheduleService
|
|
|
return $grouped;
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
+
|
|
|
+ public function cancelWithReason(int $id, string $cancelText)
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ DB::beginTransaction();
|
|
|
+
|
|
|
+ $schedule = Schedule::findOrFail($id);
|
|
|
+
|
|
|
+ $allowedStatuses = ['accepted', 'paid', 'pending'];
|
|
|
+
|
|
|
+ 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.');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public function updateStatus($id, string $status)
|
|
|
{
|
|
|
try {
|
|
|
DB::beginTransaction();
|
|
|
+
|
|
|
$schedule = Schedule::findOrFail($id);
|
|
|
|
|
|
$allowedTransitions = [
|
|
|
@@ -298,73 +295,54 @@ class ScheduleService
|
|
|
$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,
|
|
|
+ $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!',
|
|
|
|
|
|
+ $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,
|
|
|
+ '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) {
|
|
|
|
|
|
+ if ($schedule->provider_id) {
|
|
|
$notificationService->create([
|
|
|
- 'title' => 'Pagamento confirmado!',
|
|
|
-
|
|
|
+ '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,
|
|
|
+ 'origin' => 'schedule',
|
|
|
+ 'origin_id' => $schedule->id,
|
|
|
+ 'type' => NotificationTypeEnum::SCHEDULE_PROVIDER_START->value,
|
|
|
+ 'user_id' => $schedule->provider->user_id,
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
@@ -381,47 +359,36 @@ class ScheduleService
|
|
|
break;
|
|
|
|
|
|
case 'cancelled':
|
|
|
-
|
|
|
$notificationService = app(NotificationService::class);
|
|
|
|
|
|
switch (Auth::user()->type) {
|
|
|
case 'client':
|
|
|
-
|
|
|
// PRESTADOR
|
|
|
- if ($schedule->provider_id) {
|
|
|
|
|
|
- $notificationService->create(['title' => 'Agendamento cancelado!',
|
|
|
+ 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,
|
|
|
+ '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,
|
|
|
+ $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;
|
|
|
@@ -433,45 +400,33 @@ class ScheduleService
|
|
|
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,
|
|
|
+ $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!',
|
|
|
|
|
|
+ $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,
|
|
|
+ 'origin' => 'schedule',
|
|
|
+ 'origin_id' => $schedule->id,
|
|
|
+ 'type' => NotificationTypeEnum::SCHEDULE_CLIENT_PROVIDER_FINISHED->value,
|
|
|
+ 'user_id' => $schedule->client->user_id,
|
|
|
]);
|
|
|
|
|
|
break;
|
|
|
@@ -482,81 +437,100 @@ class ScheduleService
|
|
|
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 cancelWithReason(int $id, string $cancelText)
|
|
|
+ //
|
|
|
+
|
|
|
+ private function calculateAmount(Provider $provider, string $periodType): float
|
|
|
{
|
|
|
- try {
|
|
|
- DB::beginTransaction();
|
|
|
+ $hourlyRates = [
|
|
|
+ '2' => $provider->daily_price_2h ?? 0,
|
|
|
+ '4' => $provider->daily_price_4h ?? 0,
|
|
|
+ '6' => $provider->daily_price_6h ?? 0,
|
|
|
+ '8' => $provider->daily_price_8h ?? 0,
|
|
|
+ ];
|
|
|
|
|
|
- $schedule = Schedule::findOrFail($id);
|
|
|
+ return $hourlyRates[$periodType] ?? 0;
|
|
|
+ }
|
|
|
|
|
|
- $allowedStatuses = ['accepted', 'paid', 'pending'];
|
|
|
+ private function validateProviderAvailability(array $data, $excludeScheduleId = null)
|
|
|
+ {
|
|
|
+ $provider_id = $data['provider_id'];
|
|
|
+ $client_id = $data['client_id'];
|
|
|
|
|
|
- if (! in_array($schedule->status, $allowedStatuses)) {
|
|
|
- throw new \Exception("Cancelamento não permitido para o status atual: {$schedule->status}");
|
|
|
- }
|
|
|
+ $date = Carbon::parse($data['date']);
|
|
|
|
|
|
- $cancelled_by = Auth::user()->type;
|
|
|
+ $dayOfWeek = $date->dayOfWeek;
|
|
|
+ $startTime = $data['start_time'];
|
|
|
+ $endTime = $data['end_time'];
|
|
|
+ $date_ymd = $date->format('Y-m-d');
|
|
|
+ $period = $startTime < '13:00:00' ? 'morning' : 'afternoon';
|
|
|
|
|
|
- $schedule->update([
|
|
|
- 'status' => 'cancelled',
|
|
|
- 'cancel_text' => $cancelText,
|
|
|
- 'cancelled_by' => $cancelled_by,
|
|
|
- ]);
|
|
|
+ // bloqueio 2 schedules por semana para o mesmo client e provider
|
|
|
|
|
|
- DB::commit();
|
|
|
+ ScheduleBusinessRules::validateWeeklyScheduleLimit(
|
|
|
+ $client_id,
|
|
|
+ $provider_id,
|
|
|
+ $data['date'],
|
|
|
+ $excludeScheduleId
|
|
|
+ );
|
|
|
|
|
|
- return $schedule->fresh(['client.user', 'provider.user', 'address']);
|
|
|
- } catch (\Exception $e) {
|
|
|
- DB::rollBack();
|
|
|
+ // bloqueio provider trabalha no dia/periodo
|
|
|
|
|
|
- Log::error('Erro ao cancelar agendamento: '.$e->getMessage());
|
|
|
+ ScheduleBusinessRules::validateWorkingDay(
|
|
|
+ $provider_id,
|
|
|
+ $dayOfWeek,
|
|
|
+ $period
|
|
|
+ );
|
|
|
|
|
|
- throw new \Exception('Não foi possível cancelar o agendamento.');
|
|
|
- }
|
|
|
- }
|
|
|
+ // bloqueio provider tem blockedday para dia/hora
|
|
|
|
|
|
- public function getClientProviderBlocks(int $clientId, int $providerId): array
|
|
|
- {
|
|
|
- $today = Carbon::today()->format('Y-m-d');
|
|
|
+ ScheduleBusinessRules::validateBlockedDay(
|
|
|
+ $provider_id,
|
|
|
+ $date->format('Y-m-d'),
|
|
|
+ $startTime,
|
|
|
+ $endTime
|
|
|
+ );
|
|
|
|
|
|
- $schedules = Schedule::where('client_id', $clientId)
|
|
|
- ->where('provider_id', $providerId)
|
|
|
- ->whereNotIn('status', self::EXCLUDED_STATUSES)
|
|
|
- ->whereDate('date', '>=', $today)
|
|
|
- ->orderBy('date')
|
|
|
- ->orderBy('start_time')
|
|
|
- ->get(['id', 'date', 'start_time', 'end_time', 'status']);
|
|
|
+ // bloqueio provider tem outro agendamento para dia/hora
|
|
|
|
|
|
- $existingSchedules = $schedules->map(function ($schedule) {
|
|
|
- return [
|
|
|
- 'id' => $schedule->id,
|
|
|
- 'date' => Carbon::parse($schedule->date)->format('Y-m-d'),
|
|
|
- 'start_time' => $schedule->start_time,
|
|
|
- 'end_time' => $schedule->end_time,
|
|
|
- 'status' => $schedule->status,
|
|
|
- ];
|
|
|
- })->values();
|
|
|
+ ScheduleBusinessRules::validateConflictingSchedule(
|
|
|
+ $provider_id,
|
|
|
+ $date->format('Y-m-d'),
|
|
|
+ $startTime,
|
|
|
+ $endTime,
|
|
|
+ $excludeScheduleId
|
|
|
+ );
|
|
|
|
|
|
- $fullyBlockedWeeks = $schedules
|
|
|
- ->groupBy(function ($schedule) {
|
|
|
- return Carbon::parse($schedule->date)
|
|
|
- ->startOfWeek(Carbon::SUNDAY)
|
|
|
- ->format('Y-m-d');
|
|
|
- })
|
|
|
- ->filter(function ($weekSchedules) {
|
|
|
- return $weekSchedules->count() >= 2;
|
|
|
- })
|
|
|
- ->keys()
|
|
|
- ->values();
|
|
|
+ // bloqueio provider tem outra proposta na mesma data
|
|
|
|
|
|
- return [
|
|
|
- 'existing_schedules' => $existingSchedules,
|
|
|
- 'fully_blocked_weeks' => $fullyBlockedWeeks,
|
|
|
- ];
|
|
|
+ ScheduleBusinessRules::validateConflictingProposalSameDate(
|
|
|
+ $provider_id,
|
|
|
+ $date_ymd,
|
|
|
+ $startTime,
|
|
|
+ $endTime,
|
|
|
+ null
|
|
|
+ );
|
|
|
+
|
|
|
+ // bloqueio caso o client tenha bloqueado o provider
|
|
|
+
|
|
|
+ ScheduleBusinessRules::validateClientNotBlockedByProvider(
|
|
|
+ $client_id,
|
|
|
+ $provider_id
|
|
|
+ );
|
|
|
+
|
|
|
+ // bloqueio caso o provider tenha bloqueado o client
|
|
|
+
|
|
|
+ ScheduleBusinessRules::validateProviderNotBlockedByClient(
|
|
|
+ $client_id,
|
|
|
+ $provider_id
|
|
|
+ );
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|