diff --git a/public/api/available_slots.php b/public/api/available_slots.php new file mode 100644 index 0000000..174874f --- /dev/null +++ b/public/api/available_slots.php @@ -0,0 +1,164 @@ + idservice di riferimento (il servizio + * della lezione da spostare o dell'ordine). + * - month (YYYY-MM, opz.) -> mese da mostrare, default mese corrente. + * + * Logica (identica a bookingpanel.php): + * - Prende i servizi compatibili tramite associateclass + * (idmainservice = service_id -> idassociateservice), includendo se stesso. + * - Mostra gli slot del mese di QUEI servizi. + * - Per ogni slot calcola posti liberi = maxcapacity - (prenotazioni 'booked'). + * - Indica se l'utente è già prenotato su quello slot. + * -------------------------------------------------------------------------- + */ + +require_once __DIR__ . '/_bootstrap.php'; +// Da qui: $user (autenticato) e $db (PDO) disponibili. + +$userId = (int) $user->id; + +const LESSON_LOCATION = 'via Valassina 62/B Seregno - Sala Contesto Yoga'; + +// ========================================================================== +// PARAMETRI +// ========================================================================== +$serviceId = (int) ($_GET['service_id'] ?? 0); +if ($serviceId <= 0) { + http_response_code(400); + echo json_encode(['success' => false, 'error' => 'service_id mancante']); + exit; +} + +$month = $_GET['month'] ?? date('Y-m'); +$monthDate = DateTime::createFromFormat('Y-m-d', $month . '-01'); +if ($monthDate === false) { + $month = date('Y-m'); + $monthDate = new DateTime(date('Y-m') . '-01'); +} + +$monthStart = $monthDate->format('Y-m-01'); +// bound superiore: primo giorno del mese successivo (esclusivo) +$monthEndPlus1 = (clone $monthDate)->modify('first day of next month')->format('Y-m-d'); + +// ========================================================================== +// 1) Servizi compatibili (associateclass) + il servizio stesso +// ========================================================================== +$compatibleIds = [$serviceId]; + +$stmt = $db->prepare(" + SELECT idassociateservice + FROM associateclass + WHERE idmainservice = :sid +"); +$stmt->execute([':sid' => $serviceId]); +foreach ($stmt->fetchAll() as $r) { + $compatibleIds[] = (int) $r['idassociateservice']; +} +$compatibleIds = array_values(array_unique($compatibleIds)); + +// Costruzione placeholder per IN (...) +$placeholders = implode(',', array_fill(0, count($compatibleIds), '?')); + +// ========================================================================== +// 2) Slot del mese per quei servizi +// ========================================================================== +$sql = " + SELECT + ss.idserviceschedule, + ss.idservice, + ss.dateschedule, + s.servicename, + s.colorclass, + s.maxcapacity + FROM serviceschedule ss + LEFT JOIN service s ON ss.idservice = s.idservice + WHERE ss.idservice IN ($placeholders) + AND ss.dateschedule >= ? + AND ss.dateschedule < ? + ORDER BY ss.dateschedule ASC +"; + +$params = $compatibleIds; +$params[] = $monthStart . ' 00:00:00'; +$params[] = $monthEndPlus1 . ' 00:00:00'; + +$stmt = $db->prepare($sql); +$stmt->execute($params); +$rows = $stmt->fetchAll(); + +// ========================================================================== +// 3) Per ogni slot: posti liberi + già prenotato dall'utente +// ========================================================================== +$countStmt = $db->prepare(" + SELECT COUNT(*) AS n + FROM bookingclass + WHERE idserviceschedule = :sched + AND status = 'booked' +"); + +$mineStmt = $db->prepare(" + SELECT COUNT(*) AS n + FROM bookingclass + WHERE idserviceschedule = :sched + AND iduser = :uid + AND status IN ('booked','pending') +"); + +$slots = []; +foreach ($rows as $r) { + $schedId = (int) $r['idserviceschedule']; + $maxCap = (int) ($r['maxcapacity'] ?? 0); + + $countStmt->execute([':sched' => $schedId]); + $booked = (int) ($countStmt->fetch()['n'] ?? 0); + + $mineStmt->execute([':sched' => $schedId, ':uid' => $userId]); + $alreadyMine = ((int) ($mineStmt->fetch()['n'] ?? 0)) > 0; + + $freePlaces = $maxCap - $booked; + if ($freePlaces < 0) { + $freePlaces = 0; + } + + $dt = new DateTime($r['dateschedule']); + + $slots[] = [ + 'schedule_id' => $schedId, + 'service_id' => (int) $r['idservice'], + 'datetime' => $dt->format('Y-m-d H:i:s'), + 'date' => $dt->format('Y-m-d'), + 'time' => $dt->format('H:i'), + 'class_name' => (string) ($r['servicename'] ?? ''), + 'color' => (string) ($r['colorclass'] ?? '#1ebf73'), + 'location' => LESSON_LOCATION, + 'max_capacity' => $maxCap, + 'booked_count' => $booked, + 'free_places' => $freePlaces, + 'already_booked' => $alreadyMine, + // bookabile se ci sono posti e non sei già dentro + 'bookable' => ($freePlaces > 0 && !$alreadyMine), + ]; +} + +// ========================================================================== +// OUTPUT +// ========================================================================== +echo json_encode([ + 'success' => true, + 'month' => $month, + 'service_id' => $serviceId, + 'slots' => $slots, +], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);