PHP约会预订可用时段

时间:2015-05-28 13:38:25

标签: php mysql date-range appointment availability

我正在为客户开发一个在线预订系统,我需要找到他们的客户可以选择的预约时间来预订下一次预约。

我将尝试解释当前的数据库设置:

表名:约会 - 这些是客户当前预订的约会。

+----+---------+------------+-----------+----------+--------------+------+-----------+
| id | staffid |    date    | starttime | endtime  | customername | room | treatment |
+----+---------+------------+-----------+----------+--------------+------+-----------+
|  1 |       2 | 2015-08-24 | 09:00:00  | 10:00:00 | Mr Smith     |    1 |         1 |
|  2 |       2 | 2015-08-24 | 11:00:00  | 12:00:00 | Mr Jones     |    2 |         1 |
+----+---------+------------+-----------+----------+--------------+------+-----------+

表名:员工 - 员工名单,他们工作的星期几以及相关日期轮班的开始和结束时间。

+----+------+-----------+-----------+----------+
| id | name | dayofweek | starttime | endtime  |
+----+------+-----------+-----------+----------+
|  1 | Phil |         1 | 09:00:00  | 17:00:00 |
|  2 | Lisa |         5 | 09:00:00  | 18:00:00 |
|  3 | Lisa |         3 | 09:00:00  | 17:00:00 |
|  4 | Bob  |         5 | 15:00:00  | 17:00:00 |
+----+------+-----------+-----------+----------+

表名:治疗 - 可用治疗列表

+----+-------------+----------+
| id |    Name     | duration |
+----+-------------+----------+
|  1 | Treatment 1 | 01:30:00 |
|  2 | Treatment 2 | 01:00:00 |
+----+-------------+----------+

表名: stafftreatments - 一个查找表,用于确定由哪些员工执行哪些治疗。

+----+-------+-----------+
| id | staff | treatment |
+----+-------+-----------+
|  1 |     1 |         1 |
|  2 |     2 |         1 |
+----+-------+-----------+

因此,我们可以假设治疗1由工作人员Lisa执行,但Lisa仅在周三上午9点至下午5点以及周五上午9点至下午6点之间工作。菲尔也可以进行治疗1但仅适用于周一上午9点​​至下午5点。

在我的申请中,我问用户他们想要预约的治疗方法。例如,治疗1持续90分钟。然后,客户将选择他们希望预约的日期。因此,在这个阶段,我们知道所需约会的时间长度和日期,以及随后的一周。

我将采取所选日期并在每天循环说明接下来的5天

我试图开发一个查询,让我能够根据包含预订约会的约会表显示客户可以选择的所有可用时段。

假设客户希望在8月24日预订治疗1。我们知道星期五是星期五所以5岁,我们知道Lisa的工作时间是星期五上午9点到下午6点,但她已经预约了上午9点到下午12点。

因为治疗时间为90分钟,我需要得到以下数据:

+----------+-------+----------------+--------------+
|   date   | Staff | Availablestart | Availableend |
+----------+-------+----------------+--------------+
| 24/08/15 | Lisa  | 12:00          | 13:30        |
| 24/08/15 | Lisa  | 13:30          | 15:00        |
| 24/08/15 | Lisa  | 15:00          | 16:30        |
| 24/08/15 | Lisa  | 16:30          | 18:00        |
| 24/08/15 | Bob   | 15:00          | 16:30        |
+----------+-------+----------------+--------------+

然而,下一个问题是只有4个房间可供使用,因此可以同时预订不超过4种护理。

我看过这篇文章 - Finding free blocks of time in mysql and php?

但我的退休稍微复杂一些,我不知道如何构建查询。非常感谢任何帮助。

对结构进行了一些更改,我的查询如下:

SELECT trainer, day, bookingdate, from_time, to_time, timeslot 
FROM
    (
    SELECT a.trainer
    , a.day
    , bookingdate
    , TIMEDIFF(start_time, IF(bookingdate=@prevdate,@prevend,open_time )) as timeslot
    , IF(bookingdate=@prevdate,@prevend,open_time ) as from_time
    , start_time as to_time
    , @prevend := end_time as prevend
    , @prevdate := bookingdate as prevdate
    FROM bookingavailability a
        JOIN (SELECT @prevend:=null,@prevdate:=null) as init
        INNER JOIN bookingscalendar c 
            ON a.trainer = c.trainer
            AND WEEKDAY(c.bookingdate) = a.day

    UNION

      SELECT a.trainer
    , day
    , bookingdate
    , TIMEDIFF(close_time, IFNULL(MAX(end_time),open_time) ) as timeslot
    , IFNULL(MAX(end_time),open_time) as from_time
    , close_time as to_time
    , null as prevend
    , null as prevdate
    FROM bookingavailability a
    LEFT JOIN bookingscalendar c 
        ON a.trainer = c.trainer
        AND WEEKDAY(c.bookingdate) = a.day
    GROUP BY a.trainer,day,bookingdate
    ) as gaps
WHERE timeslot > '00:00:00'
ORDER BY trainer, day, bookingdate, from_time;

包含以下数据:

+----+-------------+---------+------------+----------+-------------+------+-----------+
| id | bookingdate | trainer | start_time | end_time | customer_id | room | treatment |
+----+-------------+---------+------------+----------+-------------+------+-----------+
|  1 | 2015-08-24  |       2 | 15:00:00   | 16:00:00 | Mr Smith    |    1 |         1 |
|  2 | 2015-08-31  |       2 | 16:00:00   | 17:00:00 | Mr Jones    |    2 |         1 |

+-----------------+---------+-----+-----------+------------+-------------+
| availability_id | trainer | day | open_time | close_time | trainername |
+-----------------+---------+-----+-----------+------------+-------------+
|               4 |       1 |   2 | 09:00:00  | 17:00:00   | Lisa        |
|               6 |       1 |   4 | 09:00:00  | 17:00:00   | Lisa        |
|               7 |       1 |   5 | 09:00:00  | 17:00:00   | Lisa        |
+-----------------+---------+-----+-----------+------------+-------------+

返回的数据是:

+---------+-----+-------------+-----------+----------+----------+
| trainer | day | bookingdate | from_time | to_time  | timeslot |
+---------+-----+-------------+-----------+----------+----------+
|       1 |   2 | NULL        | 09:00:00  | 17:00:00 | 08:00:00 |
|       1 |   4 | NULL        | 09:00:00  | 17:00:00 | 08:00:00 |
|       1 |   5 | NULL        | 09:00:00  | 17:00:00 | 08:00:00 |
+---------+-----+-------------+-----------+----------+----------+

但没有显示预订日期,只是空值。

有什么想法吗?

1 个答案:

答案 0 :(得分:-1)

我没有为您提供技术解决方案,但考虑在子查询中拆分问题。 将子查询结果保存到“标志”变量中,然后像在事务中一样检查它们。 还要考虑预订确认阶段(管理页面)以避免预订冲突。

希望这有帮助