sql >> Base de Datos >  >> RDS >> Mysql

Mejores prácticas para el sistema de citas/reservas PHP/MySQL

Al final opté por un sistema que generaba marcas de tiempo para las fechas de inicio y finalización en la base de datos. Mientras revisaba, agregué un segundo al inicio y resté un segundo al final para evitar la superposición de horas para las citas.

¿Qué terminé haciendo?

Obviamente, no estoy seguro de que esta sea la mejor práctica, pero funcionó para mí. El usuario comienza seleccionando su sexo y una preferencia para el día. Esto envía una solicitud AJAX para obtener el personal disponible y varios tipos de citas (por ejemplo, teñir el cabello, cortar el cabello, etc.).

Cuando se han elegido todas las configuraciones (sexo, fecha, personal y tipo), empiezo por algunas validaciones simples:verificar la fecha, verificar si la fecha ("N") no es 7 (domingo). Si todo está bien, se inicia lo más importante:

1) El tipo de cita se obtiene de la base de datos, incluida la cantidad total de tiempo que toma este tipo (30 minutos, 45 minutos, etc.) 2) El personal disponible se obtiene (una lista completa de personas en ese día o solo una persona si uno es elegido) incluyendo sus horarios disponibles

Luego, el personal (o una persona) se enlaza, comenzando con su propia hora de inicio. En este punto tengo un conjunto de datos que contiene:

$duration (of the appointment type)
$startTime (starting time of the person selected in the loop)
$endTime (= $startTime + $duration)
$personStart (= starting time of the person)
$personEnd (= end time of the person)

Tomemos estos datos de demostración:

$duration = 30 min
$startTime = 9.00h
$endTime = 9.30h
$personStart = 9.00h
$personEnd = 12.00h

Lo que estoy haciendo aquí es:

while( $endTime < $personEnd )
{
    // Check the spot for availability
    $startTime = $endTime;
    $endTime = $startTime + $duration;
}

Obviamente, todo está simplificado en este caso. Porque cuando compruebo la disponibilidad, y el lugar no está libre. Establecí $startTime para que sea igual a la última cita encontrada y empiezo desde allí en el ciclo.

Ejemplo:

I check for a free spot at 9.00 but the spot is not free because there's an appointment from 9.00 till 10.00, then 10.00 is returned and $startTime is set to 10.00h instead of 9.30h. This is done to keep the number of queries to a minimum since there can be quiet a lot.

Función de verificación de disponibilidad

// Check Availability
public static function checkAvailability($start, $end, $ape_id)
{
  // add one second to the start to avoid results showing up on the full hour
  $start += 1;
  // remove one second from the end to avoid results showing up on the full hour
  $end -= 1;

  // $start and $end are timestamps
  $getAppointments = PRegistry::getObject('db')->query("SELECT * FROM appointments WHERE
    ((
        app_start BETWEEN '".date("Y-m-d H:i:s", $start)."' AND '".date("Y-m-d H:i:s", $end)."' 
          OR
        app_end BETWEEN '".date("Y-m-d H:i:s", $start)."' AND '".date("Y-m-d H:i:s", $end)."'
      ) 
    OR
      (
    app_start < '".date("Y-m-d H:i:s", $start)."' AND app_end > '".date("Y-m-d H:i:s", $end)."'
     ))
    AND
     ape_id = ".PRegistry::getObject('db')->escape($ape_id));

    if(PRegistry::getObject('db')->num_rows($getAppointments) == 0) {
      return true;
    } else {
      $end = 0;
      foreach(PRegistry::getObject('db')->fetch_array(MYSQLI_ASSOC, $getAppointments, false) as $app) {
        if($app['app_end'] > $end) {
          $end = $app['app_end'];
            }
    }
    return $end;
     } 
}

Dado que estoy almacenando citas como "Desde:10:00 hasta:11:00", debo asegurarme de verificar los lugares desde las 11:00:01 hasta las 11:59:59, porque de lo contrario, la cita a las 11:00 se mostrará en los resultados.

Al final de la función, en caso de que se encuentre una cita, hago un bucle de los resultados y devuelvo el final más reciente. Este es el próximo inicio en el ciclo que mencioné anteriormente.

Esperemos que esto pueda ser de ayuda para cualquiera. Solo como información:ape_id es el ID de la "Persona de la cita" con la que está vinculado.