|
|
@@ -2,6 +2,9 @@
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
|
+use App\Broadcasting\RealtimeEvent;
|
|
|
+use App\Broadcasting\RealtimeRoom;
|
|
|
+use App\Broadcasting\RealtimeService;
|
|
|
use App\Exceptions\ScheduleStatusTransitionException;
|
|
|
use App\Enums\ServicePackageStatusEnum;
|
|
|
use App\Enums\UserTypeEnum;
|
|
|
@@ -29,6 +32,10 @@ class ScheduleService
|
|
|
{
|
|
|
private const EXCLUDED_STATUSES = ['cancelled', 'rejected'];
|
|
|
|
|
|
+ public function __construct(
|
|
|
+ private readonly RealtimeService $realtime
|
|
|
+ ) {}
|
|
|
+
|
|
|
public function getAll()
|
|
|
{
|
|
|
return Schedule::with(['client.user', 'provider.user', 'address'])
|
|
|
@@ -98,6 +105,17 @@ class ScheduleService
|
|
|
}
|
|
|
|
|
|
|
|
|
+ $this->realtime->emit(
|
|
|
+ RealtimeEvent::SCHEDULE_CREATED,
|
|
|
+ $this->scheduleRooms($newSchedule),
|
|
|
+ [
|
|
|
+ 'entity' => 'schedule',
|
|
|
+ 'id' => $newSchedule->id,
|
|
|
+ 'status' => $newSchedule->status,
|
|
|
+ 'schedule_type' => $newSchedule->schedule_type,
|
|
|
+ ],
|
|
|
+ );
|
|
|
+
|
|
|
$createdSchedules[] = $newSchedule;
|
|
|
}
|
|
|
|
|
|
@@ -364,6 +382,20 @@ class ScheduleService
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+ $actor = Auth::user()?->type;
|
|
|
+
|
|
|
+ $this->realtime->emit(
|
|
|
+ RealtimeEvent::SCHEDULE_STATUS_CHANGED,
|
|
|
+ $this->scheduleRooms($schedule),
|
|
|
+ [
|
|
|
+ 'entity' => 'schedule',
|
|
|
+ 'id' => $schedule->id,
|
|
|
+ 'status' => $status,
|
|
|
+ 'schedule_type' => $schedule->schedule_type,
|
|
|
+ 'actor' => $actor instanceof UserTypeEnum ? strtolower($actor->value) : 'system',
|
|
|
+ ],
|
|
|
+ );
|
|
|
+
|
|
|
DB::commit();
|
|
|
|
|
|
return $schedule->fresh(['client.user', 'provider.user', 'address']);
|
|
|
@@ -380,46 +412,66 @@ class ScheduleService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @return RealtimeRoom[]
|
|
|
+ */
|
|
|
+ private function scheduleRooms(Schedule $schedule): array
|
|
|
+ {
|
|
|
+ $rooms = [
|
|
|
+ RealtimeRoom::schedule($schedule->id),
|
|
|
+ ];
|
|
|
+
|
|
|
+ if ($schedule->client?->user_id) {
|
|
|
+ $rooms[] = RealtimeRoom::user($schedule->client->user_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($schedule->provider?->user_id) {
|
|
|
+ $rooms[] = RealtimeRoom::user($schedule->provider->user_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $rooms;
|
|
|
+ }
|
|
|
+
|
|
|
//
|
|
|
|
|
|
public function getClientProviderBlocks(int $clientId, int $providerId): array
|
|
|
{
|
|
|
- $today = Carbon::today()->format('Y-m-d');
|
|
|
-
|
|
|
- $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']);
|
|
|
-
|
|
|
- $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();
|
|
|
-
|
|
|
- $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();
|
|
|
-
|
|
|
- return [
|
|
|
- 'existing_schedules' => $existingSchedules,
|
|
|
- 'fully_blocked_weeks' => $fullyBlockedWeeks,
|
|
|
- ];
|
|
|
+ $weekStart = Carbon::today()->startOfWeek(Carbon::SUNDAY)->format('Y-m-d');
|
|
|
+
|
|
|
+ $schedules = Schedule::where('client_id', $clientId)
|
|
|
+ ->where('provider_id', $providerId)
|
|
|
+ ->whereNotIn('status', self::EXCLUDED_STATUSES)
|
|
|
+ ->whereDate('date', '>=', $weekStart)
|
|
|
+ ->orderBy('date')
|
|
|
+ ->orderBy('start_time')
|
|
|
+ ->get(['id', 'date', 'start_time', 'end_time', 'status']);
|
|
|
+
|
|
|
+ $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();
|
|
|
+
|
|
|
+ $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();
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'existing_schedules' => $existingSchedules,
|
|
|
+ 'fully_blocked_weeks' => $fullyBlockedWeeks,
|
|
|
+ ];
|
|
|
}
|
|
|
|
|
|
public function getFinished()
|
|
|
@@ -526,6 +578,20 @@ class ScheduleService
|
|
|
|
|
|
$this->cascadeCancelServicePackages($schedule, $cancelText, $cancelled_by);
|
|
|
|
|
|
+ $actor = Auth::user()?->type;
|
|
|
+
|
|
|
+ $this->realtime->emit(
|
|
|
+ RealtimeEvent::SCHEDULE_STATUS_CHANGED,
|
|
|
+ $this->scheduleRooms($schedule),
|
|
|
+ [
|
|
|
+ 'entity' => 'schedule',
|
|
|
+ 'id' => $schedule->id,
|
|
|
+ 'status' => 'cancelled',
|
|
|
+ 'schedule_type' => $schedule->schedule_type,
|
|
|
+ 'actor' => $actor instanceof UserTypeEnum ? strtolower($actor->value) : 'system',
|
|
|
+ ],
|
|
|
+ );
|
|
|
+
|
|
|
DB::commit();
|
|
|
|
|
|
return $schedule->fresh(['client.user', 'provider.user', 'address']);
|