Booking System

Par Bed0sk!l, il y a 9 ans


Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

Table bookings

+-----------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+----------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | room_id | int(11) | NO | | NULL | | | check_in | date | NO | | NULL | | | check_out | date | NO | | NULL | | | created | datetime | NO | | NULL | | | modified | datetime | NO | | NULL | | +-----------+----------+------+-----+---------+-------+ $check_in = new Date($this->request->data['check_in']); $check_out = new Date($this->request->data['check_out']); $bookings = $this->Bookings->find('all') ->contain(['Rooms']) ->where([ 'Bookings.check_in <=' => $check_in, 'Bookings.check_out >=' => $check_out ]);

Ce que je veux

Je souhaite afficher les chambres disponible en fonction d'une date d'entrée ($this->request->data['check_in']) et d'une date de sortie ($this->request->data['check_out']), je tourne en rond dans ma réflexion, puis-je le faire en une seul requête ou au contraire en plusieurs ?

Exploration en cours :

$rooms = $this->Rooms->find('all') ->contain(['Bookings']) ->matching('Bookings', function ($q) use ($check_in, $check_out) { return $q->where([ 'Bookings.check_in <=' => $check_in, 'Bookings.check_out >=' => $check_out ]); });

6 réponses

Kareylo, il y a 9 ans

Ca doit être faisable en une seule requête dans ce genre :

$rooms = $this->Rooms->find('all') ->contain(['Bookings']) ->matching('Bookings', function ($q) use ($check_in, $check_out) { return $q ->where(['NOT' => function ($q) use ($check_in, $check_out) { return $q->between('Bookings.check_in', $check_in, $check_out); } ]) ->orWhere(['NOT' => function ($q) use ($check_in, $check_out) { return $q->between('Bookings.check_out', $check_in, $check_out); } ]); });
Bed0sk!l, il y a 9 ans

Merci @Kareylo, en effet ta requête m'affiche les chambres booké, seulement je souhaite les chambres non booké, la requête que j’effectue en SQL :

$results = $connection ->execute(' SELECT rooms.id FROM rooms LEFT JOIN bookings ON ( bookings.room_id = rooms.id AND NOT ( (bookings.check_in < :check_in and bookings.check_out < :check_in) OR (bookings.check_in > :check_out and bookings.check_out > :check_out) ) ) WHERE bookings.room_id IS NULL; ', [ 'check_in' => $check_in->format('Y-m-d'), 'check_out' => $check_out->format('Y-m-d') ]) ->fetchAll('assoc');

Sais tu si je peux l’effectuer avec le SQL Query de CakePHP pour respecter la syntaxe ?

Kareylo, il y a 9 ans

Tu retires juste les 'NOT' => :)
donc :

$rooms = $this->Rooms->find('all') ->contain(['Bookings']) ->matching('Bookings', function ($q) use ($check_in, $check_out) { return $q ->where(function ($q) use ($check_in, $check_out) { return $q->between('Bookings.check_in', $check_in, $check_out); } ) ->orWhere(function ($q) use ($check_in, $check_out) { return $q->between('Bookings.check_out', $check_in, $check_out); } ); });
Bed0sk!l, il y a 9 ans

J'ai toujours les chambres non disponibles avec les deux requêtes, c'est à n'y rien comprendre

Kareylo, il y a 9 ans

Effectivement, c'est à ne rien y comprendre...

Bed0sk!l, il y a 9 ans

C'est bon avec le notMatching

$roomsAvailable = $this->Rooms->find('all') ->contain(['Bookings']) ->notMatching('Bookings', function ($q) use ($check_in, $check_out) { return $q ->where(function ($q) use ($check_in, $check_out) { return $q->between('Bookings.check_in', $check_in, $check_out); } ) ->orWhere(function ($q) use ($check_in, $check_out) { return $q->between('Bookings.check_out', $check_in, $check_out); } ); });

Merci pour ta contribution.