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