226 lines
8.6 KiB
PHP
226 lines
8.6 KiB
PHP
<?php
|
|
require_once('include/headscript.php');
|
|
|
|
/**
|
|
* Inserisce un partecipante in una classe (bookingclass).
|
|
*
|
|
* Modalità (campo bkmode dal modale):
|
|
* - 'scala' : aggancia a un ordine esistente (idorder valorizzato), consuma ticket
|
|
* - 'omaggio' : idorder NULL, is_gift='Y' (non consuma, non spostabile)
|
|
* - 'nuovo' : crea un nuovo orderbook (1 ticket, maxreschedule 0, scadenza da new_expiry)
|
|
* e vi aggancia la prenotazione
|
|
*
|
|
* Nota FK: bookingclass.idorder ha una foreign key verso orderbook.
|
|
* Quindi idorder deve essere NULL o un idorderbook reale, MAI 0.
|
|
*
|
|
* Se l'utente non esiste (userid mancante), lo crea in auth_users
|
|
* riusando un eventuale account con la stessa email. Tutto in transazione.
|
|
*/
|
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
|
|
|
// --- Input ---
|
|
$name = trim($_POST['name'] ?? '');
|
|
$surname = trim($_POST['surname'] ?? '');
|
|
$email = trim($_POST['email'] ?? '');
|
|
$userid = isset($_POST['userid']) ? (int) $_POST['userid'] : 0;
|
|
$idserviceschedule = isset($_POST['idserviceschedule']) ? (int) $_POST['idserviceschedule'] : 0;
|
|
$status = trim($_POST['status'] ?? 'booked');
|
|
$idservice = isset($_POST['idservice']) ? (int) $_POST['idservice'] : 0;
|
|
$bookingstart = trim($_POST['bookingstart'] ?? '');
|
|
|
|
// Nuovi campi dal modale
|
|
$bkmode = trim($_POST['bkmode'] ?? 'scala'); // scala | omaggio | nuovo
|
|
$idorderRaw = $_POST['idorder'] ?? '';
|
|
$newExpiry = trim($_POST['new_expiry'] ?? '');
|
|
|
|
// --- Validazione minima ---
|
|
if ($idserviceschedule <= 0 || $idservice <= 0) {
|
|
header('Location: adminpanel.php?error=missingdata');
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
$pdo->beginTransaction();
|
|
|
|
// ------------------------------------------------------------------
|
|
// 1) Risolvi / crea utente
|
|
// ------------------------------------------------------------------
|
|
if ($userid <= 0) {
|
|
if ($email !== '') {
|
|
$check = $pdo->prepare("SELECT id FROM auth_users WHERE email = :email LIMIT 1");
|
|
$check->execute([':email' => $email]);
|
|
$existing = $check->fetchColumn();
|
|
if ($existing) {
|
|
$userid = (int) $existing;
|
|
}
|
|
}
|
|
|
|
if ($userid <= 0) {
|
|
$randomPassword = bin2hex(random_bytes(8));
|
|
$hashed = password_hash($randomPassword, PASSWORD_BCRYPT);
|
|
|
|
$insUser = $pdo->prepare(
|
|
"INSERT INTO auth_users
|
|
(first_name, last_name, email, password, role_id, status, created_at, avatar)
|
|
VALUES
|
|
(:first, :last, :email, :password, :role, :status, :created, :avatar)"
|
|
);
|
|
$insUser->execute([
|
|
':first' => $name,
|
|
':last' => $surname,
|
|
':email' => $email !== '' ? $email : null,
|
|
':password' => $hashed,
|
|
':role' => 2,
|
|
':status' => 'Active',
|
|
':created' => date('Y-m-d H:i:s'),
|
|
':avatar' => 'mediationb.png',
|
|
]);
|
|
$userid = (int) $pdo->lastInsertId();
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
// 2) Determina idorder e is_gift in base alla modalità
|
|
// ------------------------------------------------------------------
|
|
$idorder = null; // default NULL (rispetta la FK)
|
|
$isGift = 'N';
|
|
|
|
if ($bkmode === 'omaggio') {
|
|
// Omaggio: nessun ordine, flag gift
|
|
$idorder = null;
|
|
$isGift = 'Y';
|
|
} elseif ($bkmode === 'nuovo') {
|
|
// Crea un nuovo ordine con 1 ticket, maxreschedule 0
|
|
if ($newExpiry === '') {
|
|
throw new RuntimeException('Scadenza mancante per il nuovo ordine.');
|
|
}
|
|
|
|
// Recupera i dati reali dell'utente (email, nome, cognome)
|
|
$uStmt = $pdo->prepare(
|
|
"SELECT first_name, last_name, email FROM auth_users WHERE id = :uid LIMIT 1"
|
|
);
|
|
$uStmt->execute([':uid' => $userid]);
|
|
$uRow = $uStmt->fetch() ?: [];
|
|
$uEmail = $uRow['email'] ?? ($email !== '' ? $email : null);
|
|
$uFirst = $uRow['first_name'] ?? $name;
|
|
$uLast = $uRow['last_name'] ?? $surname;
|
|
|
|
// Recupera il nome del servizio (per cod / product_name)
|
|
$sStmt = $pdo->prepare(
|
|
"SELECT servicename FROM service WHERE idservice = :sid LIMIT 1"
|
|
);
|
|
$sStmt->execute([':sid' => $idservice]);
|
|
$serviceName = (string) ($sStmt->fetchColumn() ?: '');
|
|
|
|
// first_lesson_date = data della lezione (solo parte data di bookingstart)
|
|
$firstLessonDate = null;
|
|
if ($bookingstart !== '') {
|
|
try {
|
|
$firstLessonDate = (new DateTime($bookingstart))->format('Y-m-d');
|
|
} catch (Throwable $e) {
|
|
$firstLessonDate = null;
|
|
}
|
|
}
|
|
|
|
$insOrder = $pdo->prepare(
|
|
"INSERT INTO orderbook
|
|
(iduser, idservice, nticket, quantity, quantityclass,
|
|
expireon, maxreschedule, reprogrammed, status,
|
|
order_billing_email, cod, product_name,
|
|
first_name, last_name, first_lesson_date, order_date_created)
|
|
VALUES
|
|
(:uid, :service, 1, 1, 1,
|
|
:expire, 0, 0, 'booked',
|
|
:bemail, :cod, :pname,
|
|
:first, :last, :firstlesson, :created)"
|
|
);
|
|
$insOrder->execute([
|
|
':uid' => $userid,
|
|
':service' => $idservice,
|
|
':expire' => $newExpiry,
|
|
':bemail' => $uEmail,
|
|
':cod' => $serviceName,
|
|
':pname' => $serviceName,
|
|
':first' => $uFirst,
|
|
':last' => $uLast,
|
|
':firstlesson' => $firstLessonDate,
|
|
':created' => date('Y-m-d'),
|
|
]);
|
|
$idorder = (int) $pdo->lastInsertId();
|
|
$isGift = 'N';
|
|
} else {
|
|
// 'scala': aggancia a ordine esistente
|
|
$idorder = ($idorderRaw !== '' && (int) $idorderRaw > 0) ? (int) $idorderRaw : null;
|
|
|
|
// Se non è stato passato un ordine valido in modalità scala,
|
|
// per sicurezza NON forziamo 0 (romperebbe la FK): resta NULL.
|
|
if ($idorder !== null) {
|
|
// Verifica che l'ordine sia dell'utente e non scaduto
|
|
$chk = $pdo->prepare(
|
|
"SELECT expireon FROM orderbook
|
|
WHERE idorderbook = :oid AND iduser = :uid LIMIT 1"
|
|
);
|
|
$chk->execute([':oid' => $idorder, ':uid' => $userid]);
|
|
$row = $chk->fetch();
|
|
if (!$row) {
|
|
throw new RuntimeException('Ordine non valido per questo utente.');
|
|
}
|
|
$exp = $row['expireon'] ?? null;
|
|
if ($exp !== null && $exp < date('Y-m-d')) {
|
|
throw new RuntimeException('Il pacchetto selezionato è scaduto.');
|
|
}
|
|
}
|
|
$isGift = 'N';
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
// 2b) Controllo anti-duplicato: utente già in questa classe?
|
|
// ------------------------------------------------------------------
|
|
$dup = $pdo->prepare(
|
|
"SELECT COUNT(*) FROM bookingclass
|
|
WHERE iduser = :uid
|
|
AND idserviceschedule = :idschedule
|
|
AND status != 'cancelled'"
|
|
);
|
|
$dup->execute([
|
|
':uid' => $userid,
|
|
':idschedule' => $idserviceschedule,
|
|
]);
|
|
if ((int) $dup->fetchColumn() > 0) {
|
|
$pdo->rollBack();
|
|
header('Location: adminpanel.php?error=duplicate');
|
|
exit;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
// 3) Inserimento prenotazione
|
|
// ------------------------------------------------------------------
|
|
$insBooking = $pdo->prepare(
|
|
"INSERT INTO bookingclass
|
|
(iduser, idserviceschedule, status, idorder, idservice, bookingstart, is_gift)
|
|
VALUES
|
|
(:iduser, :idschedule, :status, :idorder, :idservice, :bookingstart, :isgift)"
|
|
);
|
|
$insBooking->execute([
|
|
':iduser' => $userid,
|
|
':idschedule' => $idserviceschedule,
|
|
':status' => $status,
|
|
':idorder' => $idorder, // NULL o id reale, mai 0
|
|
':idservice' => $idservice,
|
|
':bookingstart' => $bookingstart !== '' ? $bookingstart : null,
|
|
':isgift' => $isGift,
|
|
]);
|
|
|
|
$pdo->commit();
|
|
|
|
header('Location: adminpanel.php?success=added');
|
|
exit;
|
|
} catch (Throwable $ex) {
|
|
if ($pdo->inTransaction()) {
|
|
$pdo->rollBack();
|
|
}
|
|
error_log('inserisci_record error: ' . $ex->getMessage());
|
|
header('Location: adminpanel.php?error=insert');
|
|
exit;
|
|
}
|