Files
yogibook_aury_new/public/api/available_slots.php
T
2026-07-27 16:31:52 +02:00

165 lines
5.5 KiB
PHP

<?php
/**
* available_slots.php
* --------------------------------------------------------------------------
* Elenca gli slot (serviceschedule) disponibili in un mese, per:
* - RIPROGRAMMARE una lezione esistente, oppure
* - PRENOTARE una lezione nuova da un ticket.
*
* Posizione: public/api/available_slots.php
* Metodo: GET
* Auth: Bearer token (Sanctum, gestito da _bootstrap.php)
*
* Parametri (GET):
* - service_id (int, richiesto) -> 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);