Till slut valde jag ett system som genererade tidsstämplar för start- och slutdatum i databasen. Medan jag kollade la jag till en sekund till starten och subtraherade en sekund från slutet för att undvika överlappande tid för möten.
Vad gjorde jag till slut
Självklart är jag inte säker på att detta är den bästa praxisen, men det fungerade för mig. Användaren börjar med att välja sitt kön och en preferens för dagen. Detta skickar en AJAX-förfrågan för att få tillgänglig personal och olika typer av mötestyper (t.ex. färgning av hår, klippning av hår, etc).
När alla inställningar har valts (kön, datum, person och typ) börjar jag med några enkla valideringar:kollar datumet, kollar om datum("N") inte är 7 (söndag). Om allt är okej startas de viktigare sakerna:
1) Mötestypen hämtas från databasen inklusive den totala tid som denna typ tar (30 minuter, 45 minuter, etc)2) Den tillgängliga personligen hämtas (en komplett lista över personer den dagen eller bara en enskild person om en är vald) inklusive deras tillgängliga tider
Personen (eller en person) loopas sedan, med början på sin egen starttid. Vid det här laget har jag en uppsättning data som innehåller:
$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)
Låt oss ta denna demodata:
$duration = 30 min
$startTime = 9.00h
$endTime = 9.30h
$personStart = 9.00h
$personEnd = 12.00h
Det jag gör här är:
while( $endTime < $personEnd )
{
// Check the spot for availability
$startTime = $endTime;
$endTime = $startTime + $duration;
}
Uppenbarligen är det helt förenklat i det här fallet. För när jag kollar efter tillgänglighet, och platsen inte är ledig. Jag ställer in $startTime till att vara lika med det senaste mötet som hittats och börjar därifrån i slingan.
Exempel:
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.
Kontrollera tillgänglighet
// 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;
}
}
Eftersom jag lagrar möten som "Från:10.00 Till:11.00" måste jag se till att kolla platser från 11:00:01 till 11:59:59, för annars kommer mötet kl. 11:00 att synas i resultaten.
I slutet av funktionen, om ett möte hittas, loopar jag resultaten och returnerar det senaste slutet. Detta är nästa start i slingan jag nämnde ovan.
Förhoppningsvis kan detta vara till någon hjälp för någon. Precis som info:ape_id
är ID för den "Utnämningsperson" som den är länkad till.