165 lines
5.5 KiB
PHP
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);
|