Mysql
 sql >> Database >  >> RDS >> Mysql

Best practice per il sistema di appuntamenti/prenotazioni PHP/MySQL

Alla fine ho optato per un sistema che generasse timestamp per le date di inizio e fine nel database. Durante il controllo ho aggiunto un secondo all'inizio e sottratto un secondo alla fine per evitare sovrapposizioni di tempo per gli appuntamenti.

Che cosa ho finito per fare

Ovviamente non sono sicuro che questa sia la migliore pratica, ma ha funzionato per me. L'utente inizia selezionando il proprio sesso e una preferenza per il giorno. Questo invia una richiesta AJAX per ottenere il personale disponibile e vari tipi di appuntamenti (ad es. colorare i capelli, tagliare i capelli, ecc.).

Quando tutte le impostazioni sono state scelte (sesso, data, persona e tipo) comincio con alcune semplici convalide:controllo della data, controllo se la data ("N") non è 7 (domenica). Se tutto va bene, vengono avviate le cose più importanti:

1) Il tipo di appuntamento viene recuperato dal database, incluso il tempo totale impiegato da questo tipo (30 minuti, 45 minuti, ecc.)2) Viene recuperato il personale disponibile (un elenco completo delle persone in quel giorno o solo una singola persona se uno è scelto) compresi gli orari disponibili

Il personale (o una persona) viene quindi riprodotto in loop, a partire dal proprio orario di inizio. A questo punto ho un set di dati contenente:

$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)

Prendiamo questi dati demo:

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

Quello che sto facendo qui è:

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

Ovviamente, in questo caso è tutto semplificato. Perché quando controllo la disponibilità, e il posto non è libero. Ho impostato $startTime in modo che sia uguale all'ultimo appuntamento trovato e parto da lì nel ciclo.

Esempio:

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.

Funzione di verifica disponibilità

// 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;
     } 
}

Dal momento che sto memorizzando gli appuntamenti come "Da:10.00 a:11.00" devo assicurarmi di controllare gli spot dalle 11:00:01 alle 11:59:59, perché altrimenti l'appuntamento alle 11:00 verrà visualizzato nei risultati.

Alla fine della funzione, nel caso in cui venga trovato un appuntamento, eseguo ciclicamente i risultati e restituisco l'ultima fine. Questo è il prossimo inizio del ciclo che ho menzionato sopra.

Speriamo che questo possa essere di aiuto a chiunque. Solo come informazioni:ape_id è l'ID della "Persona nominativa" a cui è collegato.