From 11d1f56caa8cac41cb6a69a42d9771f63dd9f996 Mon Sep 17 00:00:00 2001 From: Hector <zs22016103@estudiantes.uv.mx> Date: Wed, 12 Mar 2025 21:32:54 -0600 Subject: [PATCH] refact: correcion de archivos --- {corregido => Proyecto}/conf/bd.sql | 0 .../controlador}/VendedorController.php | 0 .../controlador/asientos.php | 0 .../controlador}/comprobante.php | 0 {corregido => Proyecto}/controlador/venta.php | 0 {corregido => Proyecto}/index.php | 0 {corregido => Proyecto}/modelo/BaseDatos.php | 0 {corregido => Proyecto}/modelo/Boleto.php | 0 {corregido => Proyecto}/modelo/Sala.php | 0 {corregido => Proyecto}/modelo/Venta.php | 0 .../vista/comprobante.html | 0 .../vista/css/comprobante.css | 0 {corregido => Proyecto}/vista/css/index.css | 0 .../vista/images/icono.png | Bin {corregido => Proyecto}/vista/index.html | 0 .../vista/js/comprobante.js | 0 {corregido => Proyecto}/vista/js/index.js | 0 conf/bd.sql | 91 -------- controlador/asientos.php | 38 ---- controlador/procesarVenta.php | 64 ------ controlador/venta.php | 71 ------ corregido/controlador/VendedorController.php | 48 ---- corregido/controlador/comprobante.php | 17 -- index.php | 5 - modelo/BaseDatos.php | 94 -------- modelo/Boleto.php | 46 ---- modelo/Sala.php | 62 ------ modelo/Venta.php | 69 ------ vista/comprobante.html | 76 ------- vista/css/comprobante.css | 103 --------- vista/css/index.css | 199 ----------------- vista/index.html | 86 -------- vista/js/comprobante.js | 110 --------- vista/js/index.js | 208 ------------------ 34 files changed, 1387 deletions(-) rename {corregido => Proyecto}/conf/bd.sql (100%) rename {controlador => Proyecto/controlador}/VendedorController.php (100%) rename {corregido => Proyecto}/controlador/asientos.php (100%) rename {controlador => Proyecto/controlador}/comprobante.php (100%) rename {corregido => Proyecto}/controlador/venta.php (100%) rename {corregido => Proyecto}/index.php (100%) rename {corregido => Proyecto}/modelo/BaseDatos.php (100%) rename {corregido => Proyecto}/modelo/Boleto.php (100%) rename {corregido => Proyecto}/modelo/Sala.php (100%) rename {corregido => Proyecto}/modelo/Venta.php (100%) rename {corregido => Proyecto}/vista/comprobante.html (100%) rename {corregido => Proyecto}/vista/css/comprobante.css (100%) rename {corregido => Proyecto}/vista/css/index.css (100%) rename {corregido => Proyecto}/vista/images/icono.png (100%) rename {corregido => Proyecto}/vista/index.html (100%) rename {corregido => Proyecto}/vista/js/comprobante.js (100%) rename {corregido => Proyecto}/vista/js/index.js (100%) delete mode 100644 conf/bd.sql delete mode 100644 controlador/asientos.php delete mode 100644 controlador/procesarVenta.php delete mode 100644 controlador/venta.php delete mode 100644 corregido/controlador/VendedorController.php delete mode 100644 corregido/controlador/comprobante.php delete mode 100644 index.php delete mode 100644 modelo/BaseDatos.php delete mode 100644 modelo/Boleto.php delete mode 100644 modelo/Sala.php delete mode 100644 modelo/Venta.php delete mode 100644 vista/comprobante.html delete mode 100644 vista/css/comprobante.css delete mode 100644 vista/css/index.css delete mode 100644 vista/index.html delete mode 100644 vista/js/comprobante.js delete mode 100644 vista/js/index.js diff --git a/corregido/conf/bd.sql b/Proyecto/conf/bd.sql similarity index 100% rename from corregido/conf/bd.sql rename to Proyecto/conf/bd.sql diff --git a/controlador/VendedorController.php b/Proyecto/controlador/VendedorController.php similarity index 100% rename from controlador/VendedorController.php rename to Proyecto/controlador/VendedorController.php diff --git a/corregido/controlador/asientos.php b/Proyecto/controlador/asientos.php similarity index 100% rename from corregido/controlador/asientos.php rename to Proyecto/controlador/asientos.php diff --git a/controlador/comprobante.php b/Proyecto/controlador/comprobante.php similarity index 100% rename from controlador/comprobante.php rename to Proyecto/controlador/comprobante.php diff --git a/corregido/controlador/venta.php b/Proyecto/controlador/venta.php similarity index 100% rename from corregido/controlador/venta.php rename to Proyecto/controlador/venta.php diff --git a/corregido/index.php b/Proyecto/index.php similarity index 100% rename from corregido/index.php rename to Proyecto/index.php diff --git a/corregido/modelo/BaseDatos.php b/Proyecto/modelo/BaseDatos.php similarity index 100% rename from corregido/modelo/BaseDatos.php rename to Proyecto/modelo/BaseDatos.php diff --git a/corregido/modelo/Boleto.php b/Proyecto/modelo/Boleto.php similarity index 100% rename from corregido/modelo/Boleto.php rename to Proyecto/modelo/Boleto.php diff --git a/corregido/modelo/Sala.php b/Proyecto/modelo/Sala.php similarity index 100% rename from corregido/modelo/Sala.php rename to Proyecto/modelo/Sala.php diff --git a/corregido/modelo/Venta.php b/Proyecto/modelo/Venta.php similarity index 100% rename from corregido/modelo/Venta.php rename to Proyecto/modelo/Venta.php diff --git a/corregido/vista/comprobante.html b/Proyecto/vista/comprobante.html similarity index 100% rename from corregido/vista/comprobante.html rename to Proyecto/vista/comprobante.html diff --git a/corregido/vista/css/comprobante.css b/Proyecto/vista/css/comprobante.css similarity index 100% rename from corregido/vista/css/comprobante.css rename to Proyecto/vista/css/comprobante.css diff --git a/corregido/vista/css/index.css b/Proyecto/vista/css/index.css similarity index 100% rename from corregido/vista/css/index.css rename to Proyecto/vista/css/index.css diff --git a/corregido/vista/images/icono.png b/Proyecto/vista/images/icono.png similarity index 100% rename from corregido/vista/images/icono.png rename to Proyecto/vista/images/icono.png diff --git a/corregido/vista/index.html b/Proyecto/vista/index.html similarity index 100% rename from corregido/vista/index.html rename to Proyecto/vista/index.html diff --git a/corregido/vista/js/comprobante.js b/Proyecto/vista/js/comprobante.js similarity index 100% rename from corregido/vista/js/comprobante.js rename to Proyecto/vista/js/comprobante.js diff --git a/corregido/vista/js/index.js b/Proyecto/vista/js/index.js similarity index 100% rename from corregido/vista/js/index.js rename to Proyecto/vista/js/index.js diff --git a/conf/bd.sql b/conf/bd.sql deleted file mode 100644 index 3ded4c4..0000000 --- a/conf/bd.sql +++ /dev/null @@ -1,91 +0,0 @@ --- Creación de la base de datos -CREATE DATABASE IF NOT EXISTS boletos_db; -USE boletos_db; - --- Tabla de salas -CREATE TABLE IF NOT EXISTS salas ( - id INT AUTO_INCREMENT PRIMARY KEY, - nombre VARCHAR(100) NOT NULL, - filas INT NOT NULL, - asientos_por_fila INT NOT NULL -); - --- Tabla de boletos -CREATE TABLE IF NOT EXISTS boletos ( - id INT AUTO_INCREMENT PRIMARY KEY, - id_sala INT NOT NULL, - fila INT NOT NULL, - numero INT NOT NULL, - precio DECIMAL(10,2) NOT NULL, - estado ENUM('disponible', 'vendido') DEFAULT 'disponible', - FOREIGN KEY (id_sala) REFERENCES salas(id), - UNIQUE KEY unique_asiento (id_sala, fila, numero) -); - --- Tabla de ventas -CREATE TABLE IF NOT EXISTS ventas ( - id VARCHAR(36) PRIMARY KEY, - fecha DATETIME NOT NULL, - nombre_cliente VARCHAR(100) NOT NULL, - total DECIMAL(10,2) NOT NULL -); - -select * from ventas; - -select * from venta_boletos; - -select * from boletos; - --- Tabla relacional venta-boletos -CREATE TABLE IF NOT EXISTS venta_boletos ( - id INT AUTO_INCREMENT PRIMARY KEY, - id_venta VARCHAR(36) NOT NULL, - id_boleto INT NOT NULL, - FOREIGN KEY (id_venta) REFERENCES ventas(id), - FOREIGN KEY (id_boleto) REFERENCES boletos(id), - UNIQUE KEY unique_venta_boleto (id_venta, id_boleto) -); - --- Insertar una sala de ejemplo -INSERT INTO salas (id, nombre, filas, asientos_por_fila) -VALUES (1, 'Sala Principal', 10, 15); - --- Procedimiento para inicializar boletos -DELIMITER // -CREATE PROCEDURE InicializaBoletos(IN sala_id INT, IN precio DECIMAL(10,2)) -BEGIN - DECLARE i INT DEFAULT 1; - DECLARE j INT DEFAULT 1; - DECLARE total_filas INT DEFAULT 0; - DECLARE total_asientos INT DEFAULT 0; - - -- Obtener dimensiones de la sala - SELECT filas, asientos_por_fila INTO total_filas, total_asientos - FROM salas WHERE id = sala_id; - - -- Depuración: Verificar valores obtenidos - SELECT CONCAT('Filas:', total_filas, ' Asientos:', total_asientos) AS Debug_Info; - - -- Si no se encuentran filas/asientos, salir del procedimiento - IF total_filas = 0 OR total_asientos = 0 THEN - SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Sala no encontrada o sin dimensiones definidas'; - END IF; - - -- Eliminar boletos existentes de la sala - DELETE FROM boletos WHERE id_sala = sala_id; - - -- Crear nuevos boletos - SET i = 1; - WHILE i <= total_filas DO - SET j = 1; - WHILE j <= total_asientos DO - INSERT INTO boletos (id_sala, fila, numero, precio, estado) - VALUES (sala_id, i, j, precio, 'disponible'); - SET j = j + 1; - END WHILE; - SET i = i + 1; - END WHILE; -END // -DELIMITER ; - -CALL InicializaBoletos(1, 50.00); \ No newline at end of file diff --git a/controlador/asientos.php b/controlador/asientos.php deleted file mode 100644 index 3d770e6..0000000 --- a/controlador/asientos.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -// api/asientos.php - API para obtener el mapa de asientos -session_start(); - -require_once '../modelo/BaseDatos.php'; -require_once '../modelo/Sala.php'; -require_once '../modelo/Boleto.php'; -require_once '../modelo/Venta.php'; -require_once 'VendedorController.php'; - -header('Content-Type: application/json'); - -// Conexión a base de datos -$db = new BaseDatos('localhost:3306', 'root', 'password', 'boletos_db'); - -// Inicializar el controlador -$vendedorController = new VendedorController($db); - -// Cargar sala (solo hay una sala con id=1) -$sala = $vendedorController->cargarSala(1); - -// Si no hay sala, podríamos inicializarla para desarrollo -if (!$sala) { - $sala = new Sala(1, 'Sala Principal'); - $sala->inicializarBoletos(10, 15, 50.00); // 10 filas, 15 asientos por fila, $50 cada uno -} - -// Obtener mapa de asientos -$mapaAsientos = $vendedorController->mostrarDisponibilidadAsientos(); - -// Preparar respuesta -$response = [ - 'success' => true, - 'mapa' => $mapaAsientos, - 'precio' => 50.00 // Agregamos el precio de los boletos a la respuesta -]; - -echo json_encode($response); \ No newline at end of file diff --git a/controlador/procesarVenta.php b/controlador/procesarVenta.php deleted file mode 100644 index 07e8775..0000000 --- a/controlador/procesarVenta.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -require_once '../modelo/BaseDatos.php'; -require_once '../modelo/Venta.php'; -require_once '../modelo/Boleto.php'; -require_once '../modelo/Sala.php'; - -error_reporting(E_ALL); -ini_set('display_errors', 1); - -// Configuración de la base de datos -$host = 'localhost'; -$usuario = 'root'; -$password = 'password'; -$nombreBD = 'boletos_db'; -$bd = new BaseDatos($host, $usuario, $password, $nombreBD); - -// Verificar que los datos fueron recibidos correctamente -if ($_SERVER['REQUEST_METHOD'] === 'POST') { - $nombreCliente = $_POST['nombre_cliente'] ?? ''; - $asientosSeleccionados = $_POST['asientos'] ?? []; - $idSala = 1; // Asegúrate de que el ID de la sala está definido - - if (empty($nombreCliente) || empty($asientosSeleccionados) || !$idSala) { - echo json_encode(['success' => false, 'message' => 'Datos incompletos']); - exit; - } - - // Cargar la sala desde la base de datos - $sala = $bd->cargarSala($idSala); - if (!$sala) { - echo json_encode(['success' => false, 'message' => 'Sala no encontrada']); - exit; - } - - // Obtener los boletos seleccionados - $boletosDisponibles = $sala->obtenerBoletosPorId($asientosSeleccionados); - if (count($boletosDisponibles) !== count($asientosSeleccionados)) { - echo json_encode(['success' => false, 'message' => 'Uno o más boletos no están disponibles']); - exit; - } - - // Calcular el total de la venta - $total = array_reduce($boletosDisponibles, function($sum, $boleto) { - return $sum + $boleto->getPrecio(); - }, 0); - - // Crear una nueva venta - $venta = new Venta($nombreCliente); - $venta->agregarBoletos($boletosDisponibles); - - // Guardar la venta en la base de datos - if ($bd->guardarVenta($venta)) { - // Guardar comprobante en sesión - $_SESSION['comprobante'] = $venta->generarComprobante(); - echo json_encode(['success' => true, 'message' => 'Venta realizada con éxito', 'redirect' => '../vista/comprobante.html']); - } else { - echo json_encode(['success' => false, 'message' => 'Error al registrar la venta']); - } -} else { - echo json_encode(['success' => false, 'message' => 'Método no permitido']); -} - -$bd->cerrarConexion(); -?> \ No newline at end of file diff --git a/controlador/venta.php b/controlador/venta.php deleted file mode 100644 index f976d92..0000000 --- a/controlador/venta.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -// api/venta.php - API para procesar ventas -session_start(); - -require_once '../modelo/BaseDatos.php'; -require_once '../modelo/Sala.php'; -require_once '../modelo/Boleto.php'; -require_once '../modelo/Venta.php'; -require_once 'VendedorController.php'; - -header('Content-Type: application/json'); - -// Verificar método de solicitud -if ($_SERVER['REQUEST_METHOD'] !== 'POST') { - echo json_encode(['success' => false, 'mensaje' => 'Método no permitido']); - exit; -} - -// Obtener datos JSON del cuerpo de la solicitud -$data = json_decode(file_get_contents('php://input'), true); - -if (!$data || !isset($data['asientos']) || !isset($data['nombre_cliente'])) { - echo json_encode(['success' => false, 'mensaje' => 'Datos incompletos']); - exit; -} - -// Extraer datos -$idsBoletos = $data['asientos']; -$nombreCliente = $data['nombre_cliente']; - -// Validar que haya asientos seleccionados -if (empty($idsBoletos)) { - echo json_encode(['success' => false, 'mensaje' => 'No se han seleccionado asientos']); - exit; -} - -// Conexión a base de datos -$db = new BaseDatos('localhost:3306', 'root', '481037', 'boletos_db'); - -// Inicializar el controlador -$vendedorController = new VendedorController($db); - -// Cargar la sala (agregando esta línea) -$vendedorController->cargarSala(1); // O el ID de sala correspondiente - -// Seleccionar boletos -$boletosSeleccionados = $vendedorController->seleccionarBoletos($idsBoletos); - -if (count($boletosSeleccionados) == 0) { - echo json_encode(['success' => false, 'mensaje' => 'No se han seleccionado asientos disponibles']); - exit; -} - -// Procesar venta -$comprobante = $vendedorController->procesarVenta($boletosSeleccionados, $nombreCliente); - -if (!$comprobante) { - echo json_encode(['success' => false, 'mensaje' => 'Error al procesar la venta. Intente nuevamente']); - exit; -} - -// Guardar comprobante en sesión -$_SESSION['comprobante'] = $comprobante; - -// Respuesta exitosa -echo json_encode([ - 'success' => true, - 'mensaje' => 'Venta procesada con éxito', - 'redirect' => '../vista/comprobante.html', - 'comprobante' => $comprobante -]); \ No newline at end of file diff --git a/corregido/controlador/VendedorController.php b/corregido/controlador/VendedorController.php deleted file mode 100644 index 4d60fab..0000000 --- a/corregido/controlador/VendedorController.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -require_once '../modelo/BaseDatos.php'; -require_once '../modelo/Sala.php'; -require_once '../modelo/Boleto.php'; -require_once '../modelo/Venta.php'; - -class VendedorController { - private $baseDatos; - private $sala; - - public function __construct($baseDatos) { - $this->baseDatos = $baseDatos; - } - - public function cargarSala($idSala) { - $this->sala = $this->baseDatos->cargarSala($idSala); - return $this->sala; - } - - public function mostrarDisponibilidadAsientos() { - if ($this->sala) { - return $this->sala->disponibilidadAsientos(); - } - return null; - } - - public function seleccionarBoletos($idsBoletos) { - if ($this->sala) { - return $this->sala->obtenerBoletosPorId($idsBoletos); - } - return []; - } - - public function procesarVenta($boletos, $nombreCliente) { - $venta = new Venta($nombreCliente); - $venta->agregarBoletos($boletos); - - if (count($venta->getBoletos()) > 0) { - $resultado = $this->baseDatos->guardarVenta($venta); - if ($resultado) { - return $venta->generarComprobante(); - } - } - - return null; - } -} \ No newline at end of file diff --git a/corregido/controlador/comprobante.php b/corregido/controlador/comprobante.php deleted file mode 100644 index 7c544d9..0000000 --- a/corregido/controlador/comprobante.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -// comprobante.php - Lógica de servidor para el comprobante de venta -session_start(); - -// Verificar si hay un comprobante en la sesión -if (!isset($_SESSION['comprobante'])) { - header('Location: ../vista/index.html'); - exit; -} - -// Obtener el comprobante de la sesión -$comprobante = $_SESSION['comprobante']; - -// Devolver datos en formato JSON para ser consumidos por JavaScript -header('Content-Type: application/json'); -echo json_encode($comprobante); -?> \ No newline at end of file diff --git a/index.php b/index.php deleted file mode 100644 index 968cc46..0000000 --- a/index.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php -// Redirigir a la página principal del sistema -header("Location: vista/index.html"); -exit(); -?> diff --git a/modelo/BaseDatos.php b/modelo/BaseDatos.php deleted file mode 100644 index c27b5a1..0000000 --- a/modelo/BaseDatos.php +++ /dev/null @@ -1,94 +0,0 @@ -<?php -require_once 'Sala.php'; -require_once 'Boleto.php'; -require_once 'Venta.php'; - -class BaseDatos { - private $conexion; - - public function __construct($host, $usuario, $password, $nombreBD) { - $this->conexion = new mysqli($host, $usuario, $password, $nombreBD); - - if ($this->conexion->connect_error) { - die("Error de conexión: " . $this->conexion->connect_error); - } - } - - public function cargarSala($idSala) { - $sala = null; - $query = "SELECT id, nombre FROM salas WHERE id = ?"; - $stmt = $this->conexion->prepare($query); - $stmt->bind_param("i", $idSala); - $stmt->execute(); - $result = $stmt->get_result(); - - if ($fila = $result->fetch_assoc()) { - $sala = new Sala($fila['id'], $fila['nombre']); - - // Cargar boletos de la sala - $queryBoletos = "SELECT id, fila, numero, precio, estado FROM boletos WHERE id_sala = ?"; - $stmtBoletos = $this->conexion->prepare($queryBoletos); - $stmtBoletos->bind_param("i", $idSala); - $stmtBoletos->execute(); - $resultBoletos = $stmtBoletos->get_result(); - - $boletos = []; - while ($filaBoleto = $resultBoletos->fetch_assoc()) { - $boleto = new Boleto($filaBoleto['id'], $filaBoleto['fila'], $filaBoleto['numero'], $filaBoleto['precio']); - if ($filaBoleto['estado'] === 'vendido') { - $boleto->marcarComoVendido(); - } - $boletos[] = $boleto; - } - - // Asignar boletos a la sala - $sala->setBoletos($boletos); - } - - return $sala; - } - - public function guardarVenta($venta) { - // Iniciar transacción - $this->conexion->begin_transaction(); - - try { - // Insertar venta - $query = "INSERT INTO ventas (id, fecha, nombre_cliente, total) VALUES (?, ?, ?, ?)"; - $stmt = $this->conexion->prepare($query); - $id = $venta->getId(); - $fecha = $venta->getFecha(); - $nombreCliente = $venta->getNombreCliente(); - $total = $venta->getTotal(); - $stmt->bind_param("sssd", $id, $fecha, $nombreCliente, $total); - $stmt->execute(); - - // Actualizar estado de boletos - foreach ($venta->getBoletos() as $boleto) { - $queryBoleto = "UPDATE boletos SET estado = 'vendido' WHERE id = ?"; - $stmtBoleto = $this->conexion->prepare($queryBoleto); - $idBoleto = $boleto->getId(); - $stmtBoleto->bind_param("i", $idBoleto); - $stmtBoleto->execute(); - - // Insertar relación venta-boleto - $queryRelacion = "INSERT INTO venta_boletos (id_venta, id_boleto) VALUES (?, ?)"; - $stmtRelacion = $this->conexion->prepare($queryRelacion); - $stmtRelacion->bind_param("si", $id, $idBoleto); - $stmtRelacion->execute(); - } - - // Confirmar transacción - $this->conexion->commit(); - return true; - } catch (Exception $e) { - // Revertir transacción en caso de error - $this->conexion->rollback(); - return false; - } - } - - public function cerrarConexion() { - $this->conexion->close(); - } -} \ No newline at end of file diff --git a/modelo/Boleto.php b/modelo/Boleto.php deleted file mode 100644 index bec7a82..0000000 --- a/modelo/Boleto.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -class Boleto { - private $id; - private $fila; - private $numero; - private $precio; - private $estado; // 'disponible' o 'vendido' - - public function __construct($id, $fila, $numero, $precio) { - $this->id = $id; - $this->fila = $fila; - $this->numero = $numero; - $this->precio = $precio; - $this->estado = 'disponible'; - } - - // Getters y setters - public function getId() { - return $this->id; - } - - public function getFila() { - return $this->fila; - } - - public function getNumero() { - return $this->numero; - } - - public function getPrecio() { - return $this->precio; - } - - public function getEstado() { - return $this->estado; - } - - public function marcarComoVendido() { - $this->estado = 'vendido'; - return true; - } - - public function estaDisponible() { - return $this->estado === 'disponible'; - } -} \ No newline at end of file diff --git a/modelo/Sala.php b/modelo/Sala.php deleted file mode 100644 index b1ea1af..0000000 --- a/modelo/Sala.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -require_once 'Boleto.php'; - -class Sala { - private $id; - private $nombre; - private $boletos = []; - - public function __construct($id, $nombre) { - $this->id = $id; - $this->nombre = $nombre; - } - - public function getId() { - return $this->id; - } - - public function getNombre() { - return $this->nombre; - } - - public function inicializarBoletos($filas, $asientosPorFila, $precio) { - $this->boletos = []; - $contador = 1; - - for ($i = 1; $i <= $filas; $i++) { - for ($j = 1; $j <= $asientosPorFila; $j++) { - $this->boletos[] = new Boleto($contador, $i, $j, $precio); - $contador++; - } - } - } - - public function obtenerBoletos() { - return $this->boletos; - } - - public function obtenerBoletosPorEstado($estado) { - return array_filter($this->boletos, function($boleto) use ($estado) { - return $boleto->getEstado() === $estado; - }); - } - - public function obtenerBoletosPorId($ids) { - return array_filter($this->boletos, function($boleto) use ($ids) { - return in_array($boleto->getId(), $ids); - }); - } - - public function disponibilidadAsientos() { - $mapa = []; - foreach ($this->boletos as $boleto) { - $mapa[$boleto->getFila()][$boleto->getNumero()] = $boleto->getEstado(); - } - return $mapa; - } - - // Setter para asignar boletos desde la base de datos - public function setBoletos($boletos) { - $this->boletos = $boletos; - } -} \ No newline at end of file diff --git a/modelo/Venta.php b/modelo/Venta.php deleted file mode 100644 index 1df14ae..0000000 --- a/modelo/Venta.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -require_once 'Boleto.php'; - -class Venta { - private $id; - private $fecha; - private $boletos = []; - private $total; - private $nombreCliente; - - public function __construct($nombreCliente) { - $this->id = bin2hex(random_bytes(8)); - date_default_timezone_set('America/Mexico_City'); - $this->fecha = date('Y-m-d H:i:s'); - $this->nombreCliente = $nombreCliente; - $this->total = 0; - } - - public function getId() { - return $this->id; - } - - public function getFecha() { - return $this->fecha; - } - - public function getNombreCliente() { - return $this->nombreCliente; - } - - public function agregarBoletos($boletos) { - foreach ($boletos as $boleto) { - if ($boleto->estaDisponible()) { - $this->boletos[] = $boleto; - $this->total += $boleto->getPrecio(); - $boleto->marcarComoVendido(); - } - } - } - - public function generarComprobante() { - $comprobante = [ - 'id_venta' => $this->id, - 'fecha' => $this->fecha, - 'cliente' => $this->nombreCliente, - 'boletos' => [], - 'total' => $this->total - ]; - - foreach ($this->boletos as $boleto) { - $comprobante['boletos'][] = [ - 'id' => $boleto->getId(), - 'fila' => $boleto->getFila(), - 'numero' => $boleto->getNumero(), - 'precio' => $boleto->getPrecio() - ]; - } - - return $comprobante; - } - - public function getTotal() { - return $this->total; - } - - public function getBoletos() { - return $this->boletos; - } -} \ No newline at end of file diff --git a/vista/comprobante.html b/vista/comprobante.html deleted file mode 100644 index b517579..0000000 --- a/vista/comprobante.html +++ /dev/null @@ -1,76 +0,0 @@ -<!DOCTYPE html> -<html lang="es"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Comprobante de Venta</title> - <link rel="stylesheet" href="css/comprobante.css"> -</head> -<body> - <div class="container"> - <h1>Comprobante de Venta</h1> - - <div class="comprobante" id="comprobante-imprimible"> - <div class="header"> - <h2>Boletos para Concierto - Sala Principal</h2> - </div> - - <div class="info-venta"> - <div> - <div class="info-item"> - <span class="info-label">Nº de Venta:</span> - <span id="id-venta"></span> - </div> - <div class="info-item"> - <span class="info-label">Fecha:</span> - <span id="fecha-venta"></span> - </div> - </div> - <div> - <div class="info-item"> - <span class="info-label">Cliente:</span> - <span id="cliente-venta"></span> - </div> - </div> - </div> - - <h3>Detalle de Boletos</h3> - <table> - <thead> - <tr> - <th>#</th> - <th>Ubicación</th> - <th>Precio</th> - </tr> - </thead> - <tbody id="detalle-boletos"> - <!-- El contenido de la tabla se generará dinámicamente con JavaScript --> - </tbody> - </table> - - <div class="total"> - Total: $<span id="total-venta"></span> - </div> - - <div class="qr-container"> - <div id="qr-code"></div> - <p class="qr-info">Este QR contiene el número de venta para verificación</p> - </div> - - <div class="mensaje"> - <p>¡Gracias por su compra!</p> - <p>Este comprobante es su entrada oficial para el evento.</p> - <p>Por favor, preséntelo en la entrada del concierto.</p> - </div> - </div> - - <div class="acciones"> - <a href="index.html" class="btn">Volver a Ventas</a> - <button class="btn btn-print" onclick="imprimirComprobante()">Imprimir Comprobante</button> - </div> - </div> - - <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script> - <script src="js/comprobante.js"></script> -</body> -</html> \ No newline at end of file diff --git a/vista/css/comprobante.css b/vista/css/comprobante.css deleted file mode 100644 index fcf94c0..0000000 --- a/vista/css/comprobante.css +++ /dev/null @@ -1,103 +0,0 @@ -body { - font-family: Arial, sans-serif; - margin: 0; - padding: 20px; - background-color: #f5f5f5; -} -.container { - max-width: 800px; - margin: 0 auto; - background-color: #fff; - padding: 20px; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} -h1, h2 { - color: #333; -} -.comprobante { - border: 1px solid #ddd; - padding: 20px; - border-radius: 4px; - margin: 20px 0; -} -.header { - border-bottom: 2px solid #333; - padding-bottom: 10px; - margin-bottom: 20px; -} -.info-venta { - display: flex; - justify-content: space-between; - margin-bottom: 20px; -} -.info-item { - margin-bottom: 10px; -} -.info-label { - font-weight: bold; -} -table { - width: 100%; - border-collapse: collapse; - margin-bottom: 20px; -} -th, td { - border: 1px solid #ddd; - padding: 8px; - text-align: left; -} -th { - background-color: #f8f9fa; -} -.total { - font-size: 18px; - font-weight: bold; - text-align: right; - margin-top: 20px; - padding-top: 10px; - border-top: 1px solid #ddd; -} -.acciones { - display: flex; - justify-content: space-between; - margin-top: 20px; -} -.btn { - background-color: #007bff; - color: white; - border: none; - padding: 10px 20px; - border-radius: 4px; - text-decoration: none; - cursor: pointer; - display: inline-block; -} -.btn-print { - background-color: #6c757d; -} -.btn:hover { - opacity: 0.9; -} - -.qr-container { - text-align: center; - margin: 30px 0; - padding: 10px; - border-top: 1px dashed #ccc; - padding-top: 20px; -} -#qr-code { - display: inline-block; - margin: 0 auto; -} -.qr-info { - font-size: 14px; - margin-top: 10px; -} - -.mensaje { - margin-top: 40px; - font-size: 14px; - text-align: center; -} \ No newline at end of file diff --git a/vista/css/index.css b/vista/css/index.css deleted file mode 100644 index bb656a5..0000000 --- a/vista/css/index.css +++ /dev/null @@ -1,199 +0,0 @@ -body { - font-family: Arial, sans-serif; - margin: 0; - padding: 20px; - background-color: #f5f5f5; -} - -.container { - max-width: 1200px; - margin: 0 auto; - background-color: #fff; - padding: 20px; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} - -.main-content { - display: flex; - flex-wrap: wrap; - gap: 20px; - margin-top: 20px; -} - -.sala { - flex: 1; - min-width: 300px; - margin: 20px 0; - text-align: center; -} - -.sidebar { - flex: 0 0 350px; -} - -h1, h2 { - color: #333; -} - -.mensaje { - background-color: #f8d7da; - color: #721c24; - padding: 10px; - margin-bottom: 20px; - border-radius: 4px; - display: none; -} - -.escenario { - background-color: #ddd; - padding: 10px; - margin-bottom: 30px; - border-radius: 4px; - text-align: center; - font-weight: bold; -} - -.filas { - display: flex; - flex-direction: column; - align-items: center; - gap: 10px; -} - -.fila { - display: flex; - gap: 10px; - align-items: center; -} - -.numero-fila { - width: 30px; - text-align: center; - font-weight: bold; -} - -.asientos { - display: flex; - gap: 5px; -} - -.asiento { - width: 35px; - height: 35px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 5px; - cursor: pointer; - user-select: none; - font-size: 12px; -} - -.disponible { - background-color: #28a745; - color: white; -} - -.vendido { - background-color: #dc3545; - color: white; - cursor: not-allowed; -} - -.seleccionado { - background-color: #007bff; - color: white; -} - -.form-group { - margin-bottom: 15px; -} - -label { - display: block; - margin-bottom: 5px; - font-weight: bold; -} - -input[type="text"] { - width: 100%; - padding: 8px; - border: 1px solid #ddd; - border-radius: 4px; - box-sizing: border-box; -} - -.btn { - background-color: #007bff; - color: white; - border: none; - padding: 10px 20px; - border-radius: 4px; - cursor: pointer; -} - -.btn:hover { - background-color: #0069d9; -} - -.resumen, .concierto-detalles, #formularioVenta { - background-color: #f8f9fa; - border-radius: 4px; -} - -.resumen { - margin-top: 20px; - padding: 15px; -} - -.concierto-detalles { - border-left: 4px solid #6c757d; -} - -#formularioVenta { - padding: 20px; - border: 1px solid #ddd; - height: fit-content; -} - -.concierto-detalles i { - color: #6c757d; - margin-right: 5px; - width: 20px; - text-align: center; -} - -#formularioVenta i { - color: #495057; - margin-right: 5px; -} - -.leyenda { - display: flex; - gap: 15px; - margin-top: 20px; - justify-content: center; -} - -.leyenda-item { - display: flex; - align-items: center; - gap: 5px; -} - -.leyenda-color { - width: 20px; - height: 20px; - border-radius: 3px; -} - -@media (max-width: 992px) { - .main-content { - flex-direction: column; - } - - .sidebar { - width: 100%; - } -} \ No newline at end of file diff --git a/vista/index.html b/vista/index.html deleted file mode 100644 index d7174de..0000000 --- a/vista/index.html +++ /dev/null @@ -1,86 +0,0 @@ -<!DOCTYPE html> -<html lang="es"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Sistema de Venta de Boletos</title> - <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> - <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css"> - <link rel="stylesheet" href="css/index.css"> - <style> - - </style> - <script src="jspdf.plugin.autotable.min.js"></script> -</head> -<body> - <div class="container"> - <h1>TicketFlow</h1> - - <div id="mensajeAlerta" class="alert alert-warning d-none" role="alert"></div> - - <div class="sala"> - <h2>Selección de Asientos - Sala Principal</h2> - <div class="escenario">ESCENARIO</div> - - <div class="filas" id="mapaAsientos"> - <!-- El mapa de asientos se cargará dinámicamente con JavaScript --> - </div> - - <div class="leyenda"> - <div class="leyenda-item"> - <div class="leyenda-color" style="background-color: #28a745;"></div> - <span>Disponible</span> - </div> - <div class="leyenda-item"> - <div class="leyenda-color" style="background-color: #007bff;"></div> - <span>Seleccionado</span> - </div> - <div class="leyenda-item"> - <div class="leyenda-color" style="background-color: #dc3545;"></div> - <span>Vendido</span> - </div> - </div> - </div> - - <form id="formularioVenta"> - <div class="form-group"> - <label for="nombre_cliente">Nombre del Cliente:</label> - <input type="text" id="nombre_cliente" name="nombre_cliente" class="form-control" required> - </div> - - <div class="resumen" id="resumen"> - <h3>Resumen de Selección</h3> - <p>Asientos seleccionados: <span id="asientosSeleccionados">Ninguno</span></p> - <p>Total: $<span id="totalVenta">0.00</span></p> - <button type="submit" id="btnVender" class="btn btn-primary">Confirmar Venta</button> - </div> - - <!-- Campo oculto para almacenar IDs de asientos seleccionados --> - <div id="asientosSeleccionadosInput"></div> - - - <div class="resumen" id="resumen"> - <h3>Graficos</h3> - <table> - - <thead> - - </thead> - - <tbody> - - </tbody> - - </table> - - <!-- Campo oculto para almacenar IDs de asientos seleccionados --> - <div id="asientosSeleccionadosInput"></div> - - - - </form> - </div> - - <script src="js/index.js"></script> -</body> -</html> \ No newline at end of file diff --git a/vista/js/comprobante.js b/vista/js/comprobante.js deleted file mode 100644 index 0978029..0000000 --- a/vista/js/comprobante.js +++ /dev/null @@ -1,110 +0,0 @@ -// comprobante.js - Maneja la comunicación entre el PHP y el HTML - -// Cuando el documento esté listo, cargar los datos del comprobante -document.addEventListener('DOMContentLoaded', cargarComprobante); - -// Función para cargar los datos del comprobante desde el servidor -function cargarComprobante() { - fetch('../controlador/comprobante.php') - .then(response => { - if (!response.ok) { - throw new Error('Error al obtener los datos del comprobante'); - } - return response.json(); - }) - .then(comprobante => { - // Llenar los datos básicos del comprobante - document.getElementById('id-venta').textContent = comprobante.id_venta; - document.getElementById('fecha-venta').textContent = comprobante.fecha; - document.getElementById('cliente-venta').textContent = comprobante.cliente; - document.getElementById('total-venta').textContent = formatearNumero(comprobante.total); - - // Generar las filas de la tabla de boletos - const tablaBoletos = document.getElementById('detalle-boletos'); - let contenidoTabla = ''; - - comprobante.boletos.forEach((boleto, index) => { - contenidoTabla += ` - <tr> - <td>${index + 1}</td> - <td>Fila ${boleto.fila}, Asiento ${boleto.numero}</td> - <td>$${formatearNumero(boleto.precio)}</td> - </tr> - `; - }); - - tablaBoletos.innerHTML = contenidoTabla; - - // Generar código QR con el ID de la venta - generarQR(comprobante.id_venta); - }) - .catch(error => { - console.error('Error:', error); - alert('No se pudo cargar el comprobante. Por favor, inténtelo de nuevo.'); - window.location.href = 'index.html'; - }); -} - -// Función para generar el código QR -function generarQR(idVenta) { - // Verificar si existe el elemento donde se mostrará el QR - const qrContainer = document.getElementById('qr-code'); - if (!qrContainer) { - console.error('No se encontró el elemento para mostrar el código QR'); - return; - } - - // Limpiar el contenedor por si ya tiene contenido - qrContainer.innerHTML = ''; - - // Crear una nueva instancia de QRCode - new QRCode(qrContainer, { - text: idVenta.toString(), - width: 128, - height: 128, - colorDark: "#000000", - colorLight: "#ffffff", - correctLevel: QRCode.CorrectLevel.H // Alta corrección de errores - }); -} - -// Función para imprimir el comprobante -function imprimirComprobante() { - const contenido = document.getElementById('comprobante-imprimible').innerHTML; - const ventanaImpresion = window.open('', '_blank'); - - ventanaImpresion.document.write(` - <html> - <head> - <title>Comprobante de Venta</title> - <style> - body { font-family: Arial, sans-serif; } - .header { border-bottom: 2px solid #333; padding-bottom: 10px; margin-bottom: 20px; } - .info-venta { display: flex; justify-content: space-between; margin-bottom: 20px; } - .info-item { margin-bottom: 10px; } - .info-label { font-weight: bold; } - table { width: 100%; border-collapse: collapse; margin-bottom: 20px; } - th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } - th { background-color: #f8f9fa; } - .total { font-size: 18px; font-weight: bold; text-align: right; margin-top: 20px; padding-top: 10px; border-top: 1px solid #ddd; } - .qr-container { text-align: center; margin: 20px 0; border-top: 1px dashed #ccc; padding-top: 20px;} - #qr-code { display: inline-block; margin: 0 auto; } - .qr-info { font-size: 14px; margin-top: 10px; } - .mensaje { margin-top: 40px; font-size: 14px; text-align: center;} - </style> - </head> - <body> - ${contenido} - </body> - </html> - `); - - ventanaImpresion.document.close(); - ventanaImpresion.focus(); - ventanaImpresion.print(); -} - -// Función auxiliar para formatear números con dos decimales -function formatearNumero(numero) { - return Number(numero).toFixed(2); -} \ No newline at end of file diff --git a/vista/js/index.js b/vista/js/index.js deleted file mode 100644 index ffaa2f0..0000000 --- a/vista/js/index.js +++ /dev/null @@ -1,208 +0,0 @@ -// js/index.js - Script para manejar la interfaz de usuario y la comunicación con el backend - -document.addEventListener('DOMContentLoaded', function() { - let seleccionados = []; - const precioBoleto = 50.00; // Precio por boleto - - // Cargar el mapa de asientos al iniciar - cargarMapaAsientos(); - - // Agregar manejador para el formulario - const formulario = document.getElementById('formularioVenta'); - formulario.addEventListener('submit', validarYEnviarFormulario); - - // Función para cargar el mapa de asientos desde la API - async function cargarMapaAsientos() { - try { - const response = await fetch('../controlador/asientos.php'); - const data = await response.json(); - - console.log('Datos recibidos:', data); // Agregar este log para ver los datos recibidos - - - if (!data.success) { - mostrarMensaje('Error al cargar el mapa de asientos', 'error'); - return; - } - - renderizarMapaAsientos(data.mapa); - } catch (error) { - console.error('Error al cargar el mapa de asientos:', error); - mostrarMensaje('Error de conexión con el servidor', 'error'); - } - } - - // Función para renderizar el mapa de asientos - function renderizarMapaAsientos(mapa) { - console.log('Mapa de asientos:', mapa); // Agregar este log para ver el mapa de asientos - const contenedor = document.getElementById('mapaAsientos'); - contenedor.innerHTML = ''; - - Object.entries(mapa).forEach(([numeroFila, asientosEnFila]) => { - const filaElement = document.createElement('div'); - filaElement.className = 'fila'; - - // Crear elemento para el número de fila - const numeroFilaElement = document.createElement('div'); - numeroFilaElement.className = 'numero-fila'; - numeroFilaElement.textContent = `F${numeroFila}`; - filaElement.appendChild(numeroFilaElement); - - // Crear contenedor para los asientos - const asientosContainer = document.createElement('div'); - asientosContainer.className = 'asientos'; - - // Crear cada asiento - Object.entries(asientosEnFila).forEach(([numeroAsiento, estado]) => { - const idBoleto = ((parseInt(numeroFila) - 1) * Object.keys(asientosEnFila).length) + parseInt(numeroAsiento); - const asiento = document.createElement('div'); - - // Determinar la clase según el estado - asiento.className = `asiento ${estado === 'disponible' ? 'disponible' : 'vendido'}`; - asiento.dataset.id = idBoleto; - asiento.textContent = numeroAsiento; - - asientosContainer.appendChild(asiento); - }); - - filaElement.appendChild(asientosContainer); - contenedor.appendChild(filaElement); - }); - - // Una vez que se ha renderizado, añadir los eventos - configurarEventosAsientos(); - } - - // Configurar eventos para los asientos - function configurarEventosAsientos() { - const asientos = document.querySelectorAll('.asiento.disponible'); - - asientos.forEach(asiento => { - asiento.addEventListener('click', function() { - const asientoId = parseInt(this.getAttribute('data-id')); - - // Verificar si ya está seleccionado - const indice = seleccionados.findIndex(a => a.id === asientoId); - - if (indice === -1) { - // Agregar a seleccionados - seleccionados.push({ - id: asientoId, - elemento: this - }); - this.classList.remove('disponible'); - this.classList.add('seleccionado'); - } else { - // Quitar de seleccionados - seleccionados.splice(indice, 1); - this.classList.remove('seleccionado'); - this.classList.add('disponible'); - } - - actualizarResumen(); - }); - }); - } - - // Función para actualizar el resumen de venta - function actualizarResumen() { - const resumenAsientos = document.getElementById('asientosSeleccionados'); - const resumenTotal = document.getElementById('totalVenta'); - const asientosInput = document.getElementById('asientosSeleccionadosInput'); - - if (seleccionados.length === 0) { - resumenAsientos.textContent = 'Ninguno'; - resumenTotal.textContent = '0.00'; - - // Limpiar los inputs ocultos - if (asientosInput) { - asientosInput.innerHTML = ''; - } - } else { - // Mostrar los asientos seleccionados - const detalles = seleccionados.map(asiento => { - const fila = Math.floor((asiento.id - 1) / 15) + 1; - const numero = ((asiento.id - 1) % 15) + 1; - return `F${fila}-${numero}`; - }); - - resumenAsientos.textContent = detalles.join(', '); - resumenTotal.textContent = (seleccionados.length * precioBoleto).toFixed(2); - - // Actualizar campo oculto para el envío del formulario - if (asientosInput) { - asientosInput.innerHTML = ''; - seleccionados.forEach(asiento => { - const input = document.createElement('input'); - input.type = 'hidden'; - input.name = 'asientos[]'; - input.value = asiento.id; - asientosInput.appendChild(input); - }); - } - } - } - async function validarYEnviarFormulario(e) { - e.preventDefault(); - - if (seleccionados.length === 0) { - mostrarMensaje('Por favor, seleccione al menos un asiento.'); - return false; - } - - const nombreCliente = document.getElementById('nombre_cliente').value.trim(); - if (nombreCliente === '') { - mostrarMensaje('Por favor, ingrese el nombre del cliente.'); - return false; - } - - const formData = new FormData(); - formData.append('nombre_cliente', nombreCliente); - seleccionados.forEach(asiento => { - formData.append('asientos[]', asiento.id); - }); - - try { - const response = await fetch('../controlador/procesarVenta.php', { - method: 'POST', - body: formData - }); - - const responseText = await response.text(); // Capturar respuesta como texto para depurar - console.log('Respuesta del servidor:', responseText); - - // Intentar parsear como JSON - const data = JSON.parse(responseText); - - if (!data.success) { - mostrarMensaje(data.message || 'Error en la venta'); // Cambiar 'mensaje' a 'message' - return; - } - - // Redirigir al comprobante - window.location.href = data.redirect; - - } catch (error) { - console.error('Error al enviar la venta:', error); - mostrarMensaje('Error de conexión con el servidor', 'error'); - } - } - - // Función para mostrar mensajes - function mostrarMensaje(texto, tipo = 'warning') { - const mensajeElement = document.getElementById('mensajeAlerta'); - if (mensajeElement) { - mensajeElement.textContent = texto; - mensajeElement.className = `alert alert-${tipo === 'error' ? 'danger' : 'warning'}`; - mensajeElement.classList.remove('d-none'); - - // Ocultar después de 5 segundos - setTimeout(() => { - mensajeElement.classList.add('d-none'); - }, 5000); - } else { - // Si no existe el elemento, usar alert - alert(texto); - } - } -}); \ No newline at end of file