Bonjour,
Voila je rencontre un petit problème avec mon code.
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
]);
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
]);
});
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.
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);
}
]);
});
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 ?
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);
}
);
});
J'ai toujours les chambres non disponibles avec les deux requêtes, c'est à n'y rien comprendre