getConnection(); if (!isset($iduserlogin)) { header("Location: login.php"); exit; } function setFlash(string $type, string $text): void { $_SESSION['flash'] = ['type' => $type, 'text' => $text]; } // Verifica che sia una richiesta POST if ($_SERVER['REQUEST_METHOD'] !== 'POST') { setFlash('danger', 'Richiesta non valida.'); header("Location: appointments.php"); exit; } // Recupera i dati dal form $date = trim($_POST['date'] ?? ''); $start_time = trim($_POST['start_time'] ?? ''); $staff_id = (int)($_POST['staff_id'] ?? 0); $customer_name = trim($_POST['customer_name'] ?? ''); $customer_phone = trim($_POST['customer_phone'] ?? ''); $service_id = (int)($_POST['service_id'] ?? 0); $notes = trim($_POST['notes'] ?? ''); // Validazione base if (!$date || !$start_time || !$staff_id || !$service_id || !$customer_name) { setFlash('danger', 'Compila tutti i campi obbligatori.'); header("Location: appointments.php?date=" . urlencode($date)); exit; } try { // 1. Verifica che lo staff appartenga al salone dell'utente $stmt = $pdo->prepare(" SELECT s.shop_id, srv.duration_minutes FROM staff s JOIN shops sh ON s.shop_id = sh.id LEFT JOIN services srv ON srv.id = ? AND srv.shop_id = sh.id WHERE s.id = ? AND sh.owner_id = ? LIMIT 1 "); $stmt->execute([$service_id, $staff_id, $iduserlogin]); $check = $stmt->fetch(PDO::FETCH_ASSOC); if (!$check) { setFlash('danger', 'Staff o servizio non valido.'); header("Location: appointments.php?date=" . urlencode($date)); exit; } $shop_id = (int)$check['shop_id']; $duration = (int)$check['duration_minutes']; // 2. Calcola start_at e end_at $start_at = $date . ' ' . $start_time . ':00'; $end_timestamp = strtotime($start_at) + ($duration * 60); $end_at = date('Y-m-d H:i:s', $end_timestamp); // 3. Verifica disponibilità (evita sovrapposizioni) $stmt = $pdo->prepare(" SELECT COUNT(*) FROM appointments WHERE staff_id = ? AND status NOT IN ('cancelled', 'no_show') AND ( (start_at < ? AND end_at > ?) OR (start_at < ? AND end_at > ?) OR (start_at >= ? AND end_at <= ?) ) "); $stmt->execute([ $staff_id, $end_at, $start_at, // nuovo finisce dopo inizio esistente $end_at, $start_at, // nuovo inizia prima fine esistente $start_at, $end_at // nuovo è contenuto ]); if ((int)$stmt->fetchColumn() > 0) { setFlash('warning', 'Slot già occupato. Scegli un altro orario.'); header("Location: appointments.php?date=" . urlencode($date) . "&staff_id=" . $staff_id); exit; } // 4. Cerca o crea il cliente $customer_id = null; if ($customer_phone) { // Cerca cliente esistente per telefono $stmt = $pdo->prepare(" SELECT id FROM customers WHERE shop_id = ? AND phone = ? LIMIT 1 "); $stmt->execute([$shop_id, $customer_phone]); $existing = $stmt->fetch(PDO::FETCH_ASSOC); if ($existing) { $customer_id = (int)$existing['id']; } } // Se non trovato, crea nuovo cliente if (!$customer_id) { $names = explode(' ', $customer_name, 2); $first_name = $names[0]; $last_name = $names[1] ?? ''; $stmt = $pdo->prepare(" INSERT INTO customers (shop_id, first_name, last_name, phone, created_at) VALUES (?, ?, ?, ?, NOW()) "); $stmt->execute([$shop_id, $first_name, $last_name, $customer_phone]); $customer_id = (int)$pdo->lastInsertId(); } // 5. Inserisci l'appuntamento $stmt = $pdo->prepare(" INSERT INTO appointments ( shop_id, customer_id, staff_id, service_id, start_at, end_at, status, notes, created_at ) VALUES (?, ?, ?, ?, ?, ?, 'confirmed', ?, NOW()) "); $stmt->execute([ $shop_id, $customer_id, $staff_id, $service_id, $start_at, $end_at, $notes ]); setFlash('success', 'Appuntamento creato con successo!'); header("Location: appointments.php?date=" . urlencode($date) . "&staff_id=" . $staff_id); exit; } catch (Exception $e) { error_log("Errore creazione appuntamento: " . $e->getMessage()); setFlash('danger', 'Errore durante la creazione: ' . $e->getMessage()); header("Location: appointments.php?date=" . urlencode($date)); exit; }