reprogram api
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* api_teacher_reprogram.php
|
||||
* --------------------------------------------------------------------------
|
||||
* Sposta una prenotazione su una nuova classe schedulata.
|
||||
* Replica reprogramclass.php della webapp, con gate staff.
|
||||
* Solo staff (Admin=1 / teacher=3).
|
||||
*
|
||||
* Posizione: public/api/api_teacher_reprogram.php
|
||||
* Metodo: POST
|
||||
* Auth: Bearer token (Sanctum) via _bootstrap.php
|
||||
* Body: booking_id=<int>&schedule_id=<int>&is_reprogrammed=<Y|N>
|
||||
*
|
||||
* Regole (identiche alla webapp):
|
||||
* - status resta 'booked', lostlesson non toccato
|
||||
* - is_reprogrammed sulla prenotazione va sempre a 'Y'
|
||||
* - orderbook.reprogrammed +1 solo se flag='Y' e idorder valido
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/_bootstrap.php';
|
||||
|
||||
// Gate staff
|
||||
$roleId = (int) $user->role_id;
|
||||
if (!in_array($roleId, [1, 3], true)) {
|
||||
http_response_code(403);
|
||||
echo json_encode(['success' => false, 'message' => 'Forbidden']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$bookingId = isset($_POST['booking_id']) ? (int) $_POST['booking_id'] : 0;
|
||||
$newSchedId = isset($_POST['schedule_id']) ? (int) $_POST['schedule_id'] : 0;
|
||||
$flagReprogrammed =
|
||||
(isset($_POST['is_reprogrammed']) && $_POST['is_reprogrammed'] === 'Y') ? 'Y' : 'N';
|
||||
|
||||
if ($bookingId <= 0 || $newSchedId <= 0) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'Dati mancanti']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$db->beginTransaction();
|
||||
|
||||
// Prenotazione corrente (lock)
|
||||
$stmt = $db->prepare(
|
||||
"SELECT idbookingclass, idserviceschedule, bookingstart, idorder, iduser
|
||||
FROM bookingclass
|
||||
WHERE idbookingclass = :id
|
||||
FOR UPDATE"
|
||||
);
|
||||
$stmt->execute([':id' => $bookingId]);
|
||||
$booking = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$booking) {
|
||||
$db->rollBack();
|
||||
http_response_code(404);
|
||||
echo json_encode(['success' => false, 'message' => 'Prenotazione non trovata']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Classe destinazione
|
||||
$stmt = $db->prepare(
|
||||
"SELECT idserviceschedule, idservice, dateschedule
|
||||
FROM serviceschedule
|
||||
WHERE idserviceschedule = :id"
|
||||
);
|
||||
$stmt->execute([':id' => $newSchedId]);
|
||||
$newSchedule = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$newSchedule) {
|
||||
$db->rollBack();
|
||||
http_response_code(404);
|
||||
echo json_encode(['success' => false, 'message' => 'Classe destinazione non trovata']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Stessa classe: niente da fare
|
||||
if ((int) $booking['idserviceschedule'] === $newSchedId) {
|
||||
$db->rollBack();
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'Classe destinazione uguale a quella attuale']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Anti-duplicato: già prenotato (attivo) nella destinazione?
|
||||
$dup = $db->prepare(
|
||||
"SELECT COUNT(*)
|
||||
FROM bookingclass
|
||||
WHERE idserviceschedule = :newsched
|
||||
AND iduser = :iduser
|
||||
AND status = 'booked'
|
||||
AND idbookingclass <> :id"
|
||||
);
|
||||
$dup->execute([
|
||||
':newsched' => $newSchedId,
|
||||
':iduser' => (int) $booking['iduser'],
|
||||
':id' => $bookingId,
|
||||
]);
|
||||
if ((int) $dup->fetchColumn() > 0) {
|
||||
$db->rollBack();
|
||||
http_response_code(409);
|
||||
echo json_encode(['success' => false, 'message' => 'Allievo già prenotato in questa classe']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Valori precedenti da conservare
|
||||
$prevSchedule = $booking['idserviceschedule'];
|
||||
$prevStart = $booking['bookingstart'];
|
||||
|
||||
// Aggiorna in place
|
||||
$upd = $db->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' => (int) $newSchedule['idserviceschedule'],
|
||||
':newservice' => (int) $newSchedule['idservice'],
|
||||
':newstart' => $newSchedule['dateschedule'],
|
||||
':prevsched' => $prevSchedule,
|
||||
':prevstart' => $prevStart,
|
||||
':id' => $bookingId,
|
||||
]);
|
||||
|
||||
// Incrementa contatore riprogrammazioni se richiesto e possibile
|
||||
$idorder = $booking['idorder'] !== null ? (int) $booking['idorder'] : 0;
|
||||
if ($flagReprogrammed === 'Y' && $idorder > 0) {
|
||||
$incr = $db->prepare(
|
||||
"UPDATE orderbook
|
||||
SET reprogrammed = reprogrammed + 1
|
||||
WHERE idorderbook = :idorder"
|
||||
);
|
||||
$incr->execute([':idorder' => $idorder]);
|
||||
}
|
||||
|
||||
$db->commit();
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'booking_id' => $bookingId,
|
||||
'schedule_id' => $newSchedId,
|
||||
'reprogrammed_counted' => ($flagReprogrammed === 'Y' && $idorder > 0),
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
} catch (Throwable $ex) {
|
||||
if ($db->inTransaction()) {
|
||||
$db->rollBack();
|
||||
}
|
||||
error_log('api_teacher_reprogram error: ' . $ex->getMessage());
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore riprogrammazione']);
|
||||
}
|
||||
Reference in New Issue
Block a user