88 lines
2.5 KiB
PHP
88 lines
2.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Modules\Restaurant\Repositories;
|
||
|
|
|
||
|
|
use Exception;
|
||
|
|
use Modules\Restaurant\Models\Reservation;
|
||
|
|
use Modules\Restaurant\Models\ReservationUnavailable;
|
||
|
|
|
||
|
|
class ReservationRepository
|
||
|
|
{
|
||
|
|
public function getAll(array $filters = [])
|
||
|
|
{
|
||
|
|
$query = Reservation::with(['table', 'customer']);
|
||
|
|
|
||
|
|
if (! empty($filters['restaurant_id'])) {
|
||
|
|
$query->where('restaurant_id', $filters['restaurant_id']);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (! empty($filters['date'])) {
|
||
|
|
$query->whereDate('reservation_date', $filters['date']);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (! empty($filters['status'])) {
|
||
|
|
$query->where('status', $filters['status']);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (! empty($filters['search'])) {
|
||
|
|
$search = $filters['search'];
|
||
|
|
$query->where(function ($q) use ($search) {
|
||
|
|
$q->where('note', 'like', "%$search%");
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
$sortBy = $filters['sort_by'] ?? 'reservation_date';
|
||
|
|
$sortOrder = $filters['sort_order'] ?? 'desc';
|
||
|
|
|
||
|
|
$query->orderBy($sortBy, $sortOrder);
|
||
|
|
|
||
|
|
$perPage = $filters['perPage'] ?? 10;
|
||
|
|
|
||
|
|
return $query->paginate($perPage);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function store(array $data)
|
||
|
|
{
|
||
|
|
$this->checkAvailability($data);
|
||
|
|
|
||
|
|
return Reservation::create($data);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function checkAvailability(array $data)
|
||
|
|
{
|
||
|
|
$date = $data['reservation_date'];
|
||
|
|
$start = $data['start_time'];
|
||
|
|
$end = $data['end_time'];
|
||
|
|
$tableId = $data['table_id'];
|
||
|
|
|
||
|
|
// check unavailable tables
|
||
|
|
$unavailable = ReservationUnavailable::where('table_id', $tableId)
|
||
|
|
->where('date', $date)
|
||
|
|
->where(function ($q) use ($start, $end) {
|
||
|
|
$q->whereBetween('start_time', [$start, $end])
|
||
|
|
->orWhereBetween('end_time', [$start, $end]);
|
||
|
|
})
|
||
|
|
->exists();
|
||
|
|
|
||
|
|
if ($unavailable) {
|
||
|
|
throw new Exception('This table is unavailable for the selected time.');
|
||
|
|
}
|
||
|
|
|
||
|
|
// check existing reservations
|
||
|
|
$conflict = Reservation::where('table_id', $tableId)
|
||
|
|
->where('reservation_date', $date)
|
||
|
|
->where(function ($q) use ($start, $end) {
|
||
|
|
$q->whereBetween('start_time', [$start, $end])
|
||
|
|
->orWhereBetween('end_time', [$start, $end]);
|
||
|
|
})
|
||
|
|
->whereNotIn('status', ['cancelled'])
|
||
|
|
->exists();
|
||
|
|
|
||
|
|
if ($conflict) {
|
||
|
|
throw new Exception('This table is already booked for the selected time.');
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|