Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Melhor prática para o sistema de agendamento/reservas PHP/MySQL


No final, optei por um sistema que gerava registros de data e hora para as datas de início e término no banco de dados. Durante a verificação, adicionei um segundo ao início e subtraí um segundo do final para evitar qualquer tempo sobreposto para compromissos.

O que acabei fazendo

Obviamente, não tenho certeza de que essa seja a melhor prática, mas funcionou para mim. O usuário começa selecionando seu sexo e uma preferência para o dia. Isso envia uma solicitação AJAX para obter o pessoal disponível e vários tipos de compromissos (por exemplo, coloração de cabelo, corte de cabelo etc.).

Quando todas as configurações foram escolhidas (sexo, data, pessoal e tipo) eu começo por algumas validações simples:verificar a data, verificar se a data("N") não é 7 (domingo). Se tudo estiver bem, as coisas mais importantes são iniciadas:

1) O tipo de compromisso é buscado no banco de dados incluindo a quantidade total de tempo que este tipo leva (30 minutos, 45 minutos, etc)2) O pessoal disponível é buscado (uma lista completa de pessoas naquele dia ou apenas uma única pessoa se um é escolhido) incluindo seus horários disponíveis

O pessoal (ou uma pessoa) é então colocado em loop, começando com seu próprio horário de início. Neste ponto, tenho um conjunto de dados contendo:
$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)

Vamos pegar esses dados de demonstração:
$duration = 30 min
$startTime = 9.00h
$endTime = 9.30h
$personStart = 9.00h
$personEnd = 12.00h

O que estou fazendo aqui é:
while( $endTime < $personEnd )
{
    // Check the spot for availability
    $startTime = $endTime;
    $endTime = $startTime + $duration;
}

Obviamente, é tudo simplificado neste caso. Porque quando eu verifico a disponibilidade, e a vaga não é gratuita. Eu defino o $startTime para ser igual ao último compromisso encontrado e começo a partir daí no loop.

Exemplo:
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.

Verifique a função de disponibilidade
// 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;
     } 
}

Como estou armazenando compromissos como "De:10:00 até:11:00", tenho que verificar os horários de 11:00:01 até 11:59:59, caso contrário, o compromisso às 11:00 será exibido nos resultados.

Ao final da função, caso seja encontrado um compromisso, faço um loop nos resultados e retorno o último final. Este é o próximo início no loop que mencionei acima.

Espero que isso possa ser de alguma ajuda para qualquer um. Apenas como informação:ape_id é o ID da "Pessoa de Agendamento" com a qual está vinculado.