Créer un Système de Réservation avec Laravel Filament
Développez une application complète de gestion de réservations pour hôtels et locations saisonnières : propriétés, chambres, clients, calcul automatique des prix et tableau de bord avec statistiques en temps réel.
Apprenez à créer une application de gestion de réservations pour hôtels, appartements et locations saisonnières avec Laravel et FilamentPHP. Ce guide vous accompagne pour mettre en place un système complet avec propriétés, chambres, clients et réservations, ainsi qu'un tableau de bord avec statistiques en temps réel.
Prérequis
Avant de commencer, assurez-vous d'avoir :
- Une application Laravel installée
- FilamentPHP v4 configuré
- Le package Laravel Trend pour les graphiques
Installation des dépendances
composer require flowframe/laravel-trend
Création des Modèles et Migrations
1. Propriétés (Hôtels, Appartements, etc.)
php artisan make:model Property -m
Dans la migration :
$table->string('name');
$table->enum('type', ['hotel', 'apartment', 'house', 'villa', 'cabin'])->default('hotel');
$table->text('description')->nullable();
$table->string('address')->nullable();
$table->string('city')->nullable();
$table->string('country')->nullable();
$table->string('postal_code')->nullable();
$table->string('phone')->nullable();
$table->string('email')->nullable();
$table->string('image')->nullable();
$table->boolean('is_active')->default(true);
2. Chambres
php artisan make:model Room -m
Dans la migration :
$table->foreignId('property_id')->constrained()->cascadeOnDelete();
$table->string('name');
$table->text('description')->nullable();
$table->integer('capacity')->default(2);
$table->integer('beds')->default(1);
$table->decimal('price_per_night', 10, 2);
$table->string('image')->nullable();
$table->boolean('is_available')->default(true);
3. Clients
php artisan make:model Guest -m
Dans la migration :
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->string('phone')->nullable();
$table->string('address')->nullable();
$table->string('city')->nullable();
$table->string('country')->nullable();
$table->text('notes')->nullable();
4. Réservations
php artisan make:model Booking -m
Dans la migration :
$table->foreignId('room_id')->constrained()->cascadeOnDelete();
$table->foreignId('guest_id')->constrained()->cascadeOnDelete();
$table->date('check_in');
$table->date('check_out');
$table->integer('guests_count')->default(1);
$table->decimal('total_price', 10, 2);
$table->enum('status', ['pending', 'confirmed', 'cancelled', 'completed'])->default('pending');
$table->text('notes')->nullable();
Modèle Room avec Vérification de Disponibilité
La logique clé de l'application est la vérification de disponibilité des chambres :
class Room extends Model
{
public function isAvailableForDates(string $checkIn, string $checkOut, ?int $excludeBookingId = null): bool
{
$query = $this->bookings()
->whereNotIn('status', ['cancelled'])
->where(function ($q) use ($checkIn, $checkOut) {
$q->whereBetween('check_in', [$checkIn, $checkOut])
->orWhereBetween('check_out', [$checkIn, $checkOut])
->orWhere(function ($q2) use ($checkIn, $checkOut) {
$q2->where('check_in', '<=', $checkIn)
->where('check_out', '>=', $checkOut);
});
});
if ($excludeBookingId) {
$query->where('id', '!=', $excludeBookingId);
}
return !$query->exists();
}
}
Modèle Booking avec Statuts
class Booking extends Model
{
public function getNightsCountAttribute(): int
{
return Carbon::parse($this->check_in)->diffInDays(Carbon::parse($this->check_out));
}
public static function getStatuses(): array
{
return [
'pending' => 'En attente',
'confirmed' => 'Confirmée',
'cancelled' => 'Annulée',
'completed' => 'Terminée',
];
}
public static function getStatusColor(string $status): string
{
return match ($status) {
'pending' => 'warning',
'confirmed' => 'success',
'cancelled' => 'danger',
'completed' => 'gray',
default => 'primary',
};
}
}
Formulaire de Réservation avec Calcul Automatique
Le formulaire Filament calcule automatiquement le prix total :
class BookingForm
{
public static function calculateTotal(Get $get, Set $set): void
{
$roomId = $get('room_id');
$checkIn = $get('check_in');
$checkOut = $get('check_out');
if (!$roomId || !$checkIn || !$checkOut) {
return;
}
$room = Room::find($roomId);
if (!$room) {
return;
}
$nights = Carbon::parse($checkIn)->diffInDays(Carbon::parse($checkOut));
$total = $nights * $room->price_per_night;
$set('total_price', $total);
}
}
Les champs utilisent ->live() et ->afterStateUpdated() pour déclencher le calcul :
DatePicker::make('check_in')
->label('Date d\'arrivée')
->required()
->live()
->afterStateUpdated(fn (Get $get, Set $set) => self::calculateTotal($get, $set)),
Widget Statistiques du Dashboard
Créez un widget pour afficher les KPIs :
php artisan make:filament-widget StatsOverview --stats-overview
class StatsOverview extends StatsOverviewWidget
{
protected function getStats(): array
{
$todayBookings = Booking::whereDate('check_in', today())->count();
$pendingBookings = Booking::where('status', 'pending')->count();
$monthRevenue = Booking::whereMonth('created_at', now()->month)
->whereYear('created_at', now()->year)
->whereIn('status', ['confirmed', 'completed'])
->sum('total_price');
return [
Stat::make('Arrivées du jour', $todayBookings)
->description('Check-in aujourd\'hui')
->color('success'),
Stat::make('Réservations en attente', $pendingBookings)
->description('À confirmer')
->color('warning'),
Stat::make('Revenus du mois', number_format($monthRevenue, 2, ',', ' ') . ' €')
->description('Réservations confirmées')
->color('primary'),
];
}
}
Widget Graphique des Réservations
Utilisez Laravel Trend pour visualiser les tendances :
php artisan make:filament-widget BookingsChart --chart
class BookingsChart extends ChartWidget
{
protected ?string $heading = 'Réservations des 30 derniers jours';
protected function getData(): array
{
$data = Trend::model(Booking::class)
->between(
start: now()->subDays(30),
end: now(),
)
->perDay()
->count();
return [
'datasets' => [
[
'label' => 'Réservations',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => Carbon::parse($value->date)->format('d/m')),
];
}
protected function getType(): string
{
return 'bar';
}
}
Resources Filament
Générez les Resources pour chaque modèle :
php artisan make:filament-resource Property
php artisan make:filament-resource Room
php artisan make:filament-resource Guest
php artisan make:filament-resource Booking
Conclusion
En quelques étapes, vous avez une application complète de gestion de réservations qui :
- Gère plusieurs types de propriétés (hôtels, appartements, villas...)
- Organise les chambres avec tarification par nuit
- Maintient une base de données clients
- Vérifie automatiquement la disponibilité des chambres
- Calcule le prix total en temps réel
- Affiche un tableau de bord avec statistiques et graphiques
Cette architecture est facilement extensible pour ajouter des fonctionnalités comme les paiements en ligne, les notifications par email, ou un calendrier de disponibilité.
Obtenez le Code Source Complet
Gagnez du temps et accédez à l'intégralité du projet.
Je veux le code source