Files
2026-08-23 11:30:40 +02:00

149 lines
4.8 KiB
PHP

<?php
/**
* reprogramclass.php
*
* Sposta una prenotazione esistente su una nuova classe schedulata.
* La vecchia collocazione non viene duplicata: la riga di bookingclass
* viene aggiornata in place, conservando classe/data precedente nei
* campi idprevserviceschedule / prevbookingstart.
*
* Input (POST):
* - idbookingclass : int prenotazione da spostare
* - idserviceschedule : int nuova classe destinazione
* - is_reprogrammed : 'Y'|'N' se 'Y' incrementa orderbook.reprogrammed
*
* Regole:
* - status resta 'booked'
* - lostlesson NON viene toccato
* - is_reprogrammed sulla prenotazione va sempre a 'Y'
* - orderbook.reprogrammed +1 solo se il flag del modale è attivo e c'e un idorder valido
*
* Nota: include direttamente class/db-functions.php (dove sta DBHandlerSelect)
* invece di headscript.php, cosi non viene emesso output HTML prima del JSON.
*/
require_once('class/db-functions.php');
header('Content-Type: application/json; charset=utf-8');
function fail(string $msg, int $http = 400): void
{
http_response_code($http);
echo json_encode(['error' => $msg]);
exit;
}
$idbookingclass = isset($_POST['idbookingclass']) ? (int) $_POST['idbookingclass'] : 0;
$idnewschedule = isset($_POST['idserviceschedule']) ? (int) $_POST['idserviceschedule'] : 0;
$flagReprogrammed = (isset($_POST['is_reprogrammed']) && $_POST['is_reprogrammed'] === 'Y') ? 'Y' : 'N';
if ($idbookingclass <= 0 || $idnewschedule <= 0) {
fail('Dati mancanti per la riprogrammazione.');
}
$pdo = DBHandlerSelect::getInstance()->getConnection();
try {
$pdo->beginTransaction();
// Prenotazione corrente (lock per evitare doppie riprogrammazioni concorrenti)
$stmt = $pdo->prepare(
"SELECT idbookingclass, idserviceschedule, bookingstart, idorder, iduser
FROM bookingclass
WHERE idbookingclass = :id
FOR UPDATE"
);
$stmt->execute([':id' => $idbookingclass]);
$booking = $stmt->fetch();
if (!$booking) {
$pdo->rollBack();
fail('Prenotazione non trovata.', 404);
}
// Classe destinazione
$stmt = $pdo->prepare(
"SELECT idserviceschedule, idservice, dateschedule
FROM serviceschedule
WHERE idserviceschedule = :id"
);
$stmt->execute([':id' => $idnewschedule]);
$newSchedule = $stmt->fetch();
if (!$newSchedule) {
$pdo->rollBack();
fail('Classe di destinazione non trovata.', 404);
}
// Nessun senso spostare sulla stessa classe
if ((int) $booking['idserviceschedule'] === $idnewschedule) {
$pdo->rollBack();
fail('La classe di destinazione coincide con quella attuale.');
}
// Anti-duplicato: l'utente e gia prenotato (attivo) nella classe destinazione?
$dupStmt = $pdo->prepare(
"SELECT COUNT(*)
FROM bookingclass
WHERE idserviceschedule = :newsched
AND iduser = :iduser
AND status = 'booked'
AND idbookingclass <> :id"
);
$dupStmt->execute([
':newsched' => $idnewschedule,
':iduser' => (int) $booking['iduser'],
':id' => $idbookingclass,
]);
if ((int) $dupStmt->fetchColumn() > 0) {
$pdo->rollBack();
fail('L\'allieva e gia prenotata in questa classe.', 409);
}
// Valori precedenti da conservare
$prevSchedule = $booking['idserviceschedule']; // puo essere NULL
$prevStart = $booking['bookingstart'];
// Aggiorna la prenotazione in place
$upd = $pdo->prepare(
"UPDATE bookingclass SET
idserviceschedule = :newsched,
idservice = :newservice,
bookingstart = :newstart,
idprevserviceschedule = :prevsched,
prevbookingstart = :prevstart,
is_reprogrammed = 'Y',
status = 'booked'
WHERE idbookingclass = :id"
);
$upd->execute([
':newsched' => $newSchedule['idserviceschedule'],
':newservice' => $newSchedule['idservice'],
':newstart' => $newSchedule['dateschedule'],
':prevsched' => $prevSchedule,
':prevstart' => $prevStart,
':id' => $idbookingclass,
]);
// Incrementa il contatore riprogrammazioni sull'ordine, se richiesto e possibile
$idorder = $booking['idorder'] !== null ? (int) $booking['idorder'] : 0;
if ($flagReprogrammed === 'Y' && $idorder > 0) {
$incr = $pdo->prepare(
"UPDATE orderbook
SET reprogrammed = reprogrammed + 1
WHERE idorderbook = :idorder"
);
$incr->execute([':idorder' => $idorder]);
}
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Throwable $ex) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
fail('Errore durante la riprogrammazione: ' . $ex->getMessage(), 500);
}