Files
yogibook_aury_new/public/event_waitlist.php
T
2026-09-17 16:53:51 +02:00

60 lines
2.1 KiB
PHP

<?php
/**
* Lista d'attesa — promozione automatica.
*
* IMPORTANTE: chiamare DENTRO una transazione in cui la riga dell'evento è già
* bloccata (SELECT ... FOR UPDATE), tipicamente subito dopo aver liberato posti
* (cancellazione di una prenotazione confermata). Così due operazioni simultanee
* non promuovono oltre la capienza.
*
* Promuove in ordine di arrivo (FIFO) le prenotazioni 'waiting' che entrano nei
* posti liberi e si ferma alla prima che non ci sta, per rispettare la coda
* (non "salta" chi è davanti).
*
* @return array<int,array> le prenotazioni promosse (per inviare le email nello Step 4)
*/
if (!function_exists('promoteFromWaitlist')) {
function promoteFromWaitlist(PDO $pdo, int $eventId): array
{
$ev = $pdo->prepare("SELECT max_seats FROM events WHERE id = ?");
$ev->execute([$eventId]);
$maxSeats = (int) $ev->fetchColumn();
if ($maxSeats <= 0) {
return [];
}
$os = $pdo->prepare("SELECT COALESCE(SUM(seats),0) FROM event_bookings
WHERE event_id = ? AND status IN ('confirmed','pending')");
$os->execute([$eventId]);
$free = $maxSeats - (int) $os->fetchColumn();
if ($free <= 0) {
return [];
}
$ws = $pdo->prepare("SELECT * FROM event_bookings
WHERE event_id = ? AND status = 'waiting'
ORDER BY created_at ASC, id ASC");
$ws->execute([$eventId]);
$waiting = $ws->fetchAll(PDO::FETCH_ASSOC);
$promoted = [];
$upd = $pdo->prepare("UPDATE event_bookings SET status = 'confirmed', updated_at = NOW() WHERE id = ?");
foreach ($waiting as $w) {
$need = (int) $w['seats'];
if ($need <= $free) {
$upd->execute([$w['id']]);
$free -= $need;
$w['status'] = 'confirmed';
$promoted[] = $w;
if ($free <= 0) {
break;
}
} else {
break; // rispetta la coda
}
}
return $promoted;
}
}