我正在开展一个项目,用户可以在这里预订餐厅,但仅限于餐厅允许的日期。餐厅还可以设置在特定时间有多少座位。
因此,餐厅可以提供每周格式化的时间表,但也可以提供例外(如假期)。
我需要的是完整表示给定时间范围内的可用范围和座位。
所以例如一家餐馆有一个周的时间表,说每个工作日他们有10
个座位,但也有几个保留我需要这样的输出
所以我可以生成一个日历,用户可以看到餐厅的可用性。
+---------------------+---------------------+-----------+
| start | end | available |
+---------------------+---------------------+-----------+
| 2013-02-14 08:00:00 | 2013-02-14 17:00:00 | 10 |
| 2013-02-15 08:00:00 | 2013-02-15 12:00:00 | 8 | <= 2 reservations
| 2013-02-15 12:00:00 | 2013-02-16 15:00:00 | 4 | <= 6 reservations
| 2013-02-15 15:00:00 | 2013-02-16 15:00:00 | 7 | etc...
| 2013-02-16 15:00:00 | 2013-02-16 17:00:00 | 4 |
| 2013-02-17 08:00:00 | 2013-02-17 17:00:00 | 10 |
| 2013-02-18 12:00:00 | 2013-02-18 18:00:00 | 10 |
+---------------------+---------------------+-----------+
答案 0 :(得分:0)
我们需要两组数据:一次可用的时间和可用的座位;以及现有预订清单。
CREATE TABLE IF NOT EXISTS `availability` (
`dayOpen` date NOT NULL,
`open` time NOT NULL,
`close` time NOT NULL,
`seats` tinyint unsigned NOT NULL,
PRIMARY KEY (`dayOpen`)
) ;
CREATE TABLE IF NOT EXISTS `reservations` (
`reservationsid` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`dayOpen` date NOT NULL,
`start` time NOT NULL,
`seatsUsed` tinyint unsigned NOT NULL,
PRIMARY KEY (`reservationsid`)
) ;
我将假设您的预订必须从小时开始,持续59分钟。这意味着我们的结果集将是使用座位数的小时列表。然后拉出可用时间并循环查看每小时的列表以及可用的座位数。
<?php
$pdoHandle = new PDO($dsn,$user,$password);
// Get all the used seats. Add WHERE with date range to limit results
$query = 'SELECT dayOpen, start, SUM(seatsUsed) as seatsBooked FROM reservations GROUP BY dayOpen, start';
$results = $pdoHandle->query($query);
$allSeatsUsed = array();
while ( $row = $results->fetch(PDO::FETCH_OBJ) )
{ $allSeatsUsed[ $row->dayOpen ][ $row->start ] = $row->seatsBooked; }
// GET all possibile seats. Add WHERE with date range to limit results
$query = 'SELECT * FROM availability ORDER BY dayOpen';
$results = $pdoHandle->query($query);
$allSeatsPossible = $results->fetchall(PDO::FETCH_OBJ);
// got through each day to limit results to only open seats
$finalOpenList = array();
foreach ( $allSeatsPossible as $dayOpen )
{
$finalOpenList[ $dayOpen->dayOpen ] = array();
$open = new DateTime($dayOpen->open);
$close = new DateTime($dayOpen-close);
$interval = new DateInterval('P1H');
$todaysSlots = new DatePeriod($open,$interval,$close);
foreach ( $todaysSlots as $slot )
{
if ( $allSeatsUsed[ $dayOpen->dayOpen ][ $slot->format('H:i:s') ] < $dayOpen->seats )
{ $finalOpenList[ $dayOpen->dayOpen ][ $slot->format('H:i:s') ] =
$dayOpen->seats -
$allSeatsUsed[ $dayOpen->dayOpen ][ $slot->format('H:i:s') ]; }
}
}
// $finalOpenList contains a list of days, with each day
// holding a list of hours and the number of slots left per hour
foreach ( $finalOpenList as $day => $hours )
{
$day = new DateTime($day);
print '<p>'.$day->format('M j, Y').': ';
if ( sizeof($hours) == 0 )
{ print 'All seats booked.</p>'; }
else
{
print '</p><ul>';
foreach ( $hours as $hour=>$seatsLeft )
{ print '<li>'.$hour.': '.$seatsLeft.' seats available.</li>'; }
print '</ul>';
}
}
?>