From bdb232333f2355110925ae25f0593b71153ce8ec Mon Sep 17 00:00:00 2001 From: "Luis.Aguilar" <aguilar.luiseder27@gmail.com> Date: Sun, 9 Mar 2025 11:31:52 -0600 Subject: [PATCH] =?UTF-8?q?Modificado=20VentaBoletos.java=20y=20a=C3=B1adi?= =?UTF-8?q?da=20VentanaPago.java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../saladeconciertos/VentaBoletos.java | 145 ++++++++++++++++-- .../example/saladeconciertos/VentanaPago.java | 119 ++++++++++++++ 2 files changed, 252 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/example/saladeconciertos/VentanaPago.java diff --git a/src/main/java/org/example/saladeconciertos/VentaBoletos.java b/src/main/java/org/example/saladeconciertos/VentaBoletos.java index 0c7819e..39d41c3 100644 --- a/src/main/java/org/example/saladeconciertos/VentaBoletos.java +++ b/src/main/java/org/example/saladeconciertos/VentaBoletos.java @@ -1,12 +1,18 @@ package org.example.saladeconciertos; import javafx.application.Application; +import javafx.geometry.Insets; +import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.Alert; // Nuevo: Importación para usar Alert +import javafx.scene.image.Image; // Nuevo: Importación para usar Image +import javafx.scene.image.ImageView; // Nuevo: Importación para usar ImageView import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; + import java.sql.*; import java.util.ArrayList; import java.util.HashMap; @@ -18,9 +24,15 @@ public class VentaBoletos extends Application { private static final String DB_USER = "sql10766655"; private static final String DB_PASSWORD = "7BZbRjEkXZ"; private List<Integer> selectedSeats = new ArrayList<>(); + private Map<Integer, Double> seatPrices = new HashMap<>(); // Nuevo: Mapa para almacenar precios de asientos + private String eventName = ""; // Nuevo: Variable para almacenar el nombre del evento + private String eventDate = ""; // Nuevo: Variable para almacenar la fecha del evento + private GridPane seatGrid; // Nuevo: Referencia a la cuadrícula de asientos + private Stage mainStage; // Nuevo: Referencia al Stage principal @Override public void start(Stage mainStage) { + this.mainStage = mainStage; // Nuevo: Guardar referencia al Stage principal int totalSeats = 0; Map<Integer, String> seatStatus = new HashMap<>(); @@ -28,14 +40,27 @@ public class VentaBoletos extends Application { Connection conexion = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); System.out.println("Conexión realizada correctamente"); - String query = "SELECT id_asiento, status FROM boleto WHERE idevento = 1"; // Cambia el idevento según corresponda - Statement statement = conexion.createStatement(); - ResultSet resultSet = statement.executeQuery(query); + // Nuevo: Obtener información del evento (nombre y fecha) + String eventQuery = "SELECT nombre, fecha FROM conciertos WHERE id = 1"; + Statement eventStatement = conexion.createStatement(); + ResultSet eventResultSet = eventStatement.executeQuery(eventQuery); - while (resultSet.next()) { - int seatId = resultSet.getInt("id_asiento"); - String status = resultSet.getString("status"); + if (eventResultSet.next()) { + eventName = eventResultSet.getString("nombre"); // Nuevo: Almacenar nombre del evento + eventDate = eventResultSet.getString("fecha"); // Nuevo: Almacenar fecha del evento + } + + // Nuevo: Obtener información de los asientos (precio base y estado) + String seatQuery = "SELECT a.id, a.precio_base, b.status FROM asientos a JOIN boleto b ON a.id = b.id_asiento WHERE b.idevento = 1"; + Statement seatStatement = conexion.createStatement(); + ResultSet seatResultSet = seatStatement.executeQuery(seatQuery); + + while (seatResultSet.next()) { + int seatId = seatResultSet.getInt("id"); + double precio = seatResultSet.getDouble("precio_base"); // Nuevo: Obtener precio del asiento + String status = seatResultSet.getString("status"); seatStatus.put(seatId, status); + seatPrices.put(seatId, precio); // Nuevo: Almacenar precio del asiento en el mapa totalSeats++; } @@ -46,9 +71,20 @@ public class VentaBoletos extends Application { } mainStage.setTitle("Gestión de Boletos"); + + // Nuevo: Título y logo + Label titleLabel = new Label("Sala de Conciertos"); + titleLabel.getStyleClass().add("title"); // Nuevo: Aplicar clase CSS + + ImageView logo = new ImageView(new Image(getClass().getResourceAsStream("/logo.png"))); // Nuevo: Cargar imagen del logo + logo.setFitWidth(100); // Nuevo: Ajustar ancho del logo + logo.setFitHeight(100); // Nuevo: Ajustar altura del logo + Label welcomeLabel = new Label("Seleccione sus asientos"); - GridPane seatGrid = new GridPane(); + seatGrid = new GridPane(); // Nuevo: Inicializar la cuadrícula de asientos + seatGrid.getStyleClass().add("seat-grid"); // Nuevo: Aplicar clase CSS Button confirmButton = new Button("Confirmar Compra"); + confirmButton.getStyleClass().add("button"); // Nuevo: Aplicar clase CSS int cols = 5; int rows = (int) Math.ceil((double) totalSeats / cols); @@ -57,16 +93,16 @@ public class VentaBoletos extends Application { int row = (seatNumber - 1) / cols; int col = (seatNumber - 1) % cols; Button seatButton = new Button("Asiento " + seatNumber); + seatButton.getStyleClass().add("seat-button"); // Nuevo: Aplicar clase CSS int finalSeatNumber = seatNumber; if ("vendido".equals(seatStatus.getOrDefault(finalSeatNumber, "disponible"))) { - seatButton.setStyle("-fx-background-color: red"); seatButton.setDisable(true); } else { seatButton.setOnAction(e -> { if (!selectedSeats.contains(finalSeatNumber)) { selectedSeats.add(finalSeatNumber); - seatButton.setStyle("-fx-background-color: green"); + seatButton.setStyle("-fx-background-color: #45a049;"); // Nuevo: Cambiar color a verde más oscuro } else { selectedSeats.remove(Integer.valueOf(finalSeatNumber)); seatButton.setStyle(""); @@ -76,13 +112,98 @@ public class VentaBoletos extends Application { seatGrid.add(seatButton, col, row); } - VBox mainLayout = new VBox(10, welcomeLabel, seatGrid, confirmButton); - Scene mainScene = new Scene(mainLayout, 400, 300); + // Nuevo: Lógica para el botón de confirmar compra + confirmButton.setOnAction(e -> { + if (selectedSeats.isEmpty()) { + mostrarAlerta("Advertencia", "No se han seleccionado asientos", "Por favor, seleccione al menos un asiento."); + } else { + final List<Integer> finalSelectedSeats = new ArrayList<>(selectedSeats); + final Map<Integer, Double> finalSeatPrices = new HashMap<>(seatPrices); + final String finalEventName = eventName; + final String finalEventDate = eventDate; + + VentanaPago ventanaPago = new VentanaPago(this); // Nuevo: Crear ventana de pago + ventanaPago.mostrarVentanaPago(finalSelectedSeats, finalSeatPrices, finalEventName, finalEventDate); + } + }); + + // Nuevo: Layout principal con logo, título, cuadrícula y botón + VBox mainLayout = new VBox(20, logo, titleLabel, welcomeLabel, seatGrid, confirmButton); + mainLayout.setAlignment(Pos.TOP_CENTER); // Nuevo: Centrar elementos + mainLayout.setPadding(new Insets(20)); // Nuevo: Agregar padding + + Scene mainScene = new Scene(mainLayout, 600, 500); // Nuevo: Aumentar tamaño de la ventana + mainScene.getStylesheets().add(getClass().getResource("/styles.css").toExternalForm()); // Nuevo: Aplicar CSS mainStage.setScene(mainScene); mainStage.show(); } + // Nuevo: Método para refrescar la interfaz después de una compra + public void refrescarInterfaz() { + selectedSeats.clear(); + Map<Integer, String> seatStatus = cargarEstadoAsientos(); + seatGrid.getChildren().clear(); + + int totalSeats = seatStatus.size(); + int cols = 5; + int rows = (int) Math.ceil((double) totalSeats / cols); + + for (int seatNumber = 1; seatNumber <= totalSeats; seatNumber++) { + int row = (seatNumber - 1) / cols; + int col = (seatNumber - 1) % cols; + Button seatButton = new Button("Asiento " + seatNumber); + seatButton.getStyleClass().add("seat-button"); // Nuevo: Aplicar clase CSS + int finalSeatNumber = seatNumber; + + if ("vendido".equals(seatStatus.getOrDefault(finalSeatNumber, "disponible"))) { + seatButton.setDisable(true); + } else { + seatButton.setOnAction(e -> { + if (!selectedSeats.contains(finalSeatNumber)) { + selectedSeats.add(finalSeatNumber); + seatButton.setStyle("-fx-background-color: #45a049;"); // Nuevo: Cambiar color a verde más oscuro + } else { + selectedSeats.remove(Integer.valueOf(finalSeatNumber)); + seatButton.setStyle(""); + } + }); + } + seatGrid.add(seatButton, col, row); + } + } + + // Nuevo: Método para cargar el estado de los asientos desde la base de datos + private Map<Integer, String> cargarEstadoAsientos() { + Map<Integer, String> seatStatus = new HashMap<>(); + + try (Connection conexion = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) { + String query = "SELECT id_asiento, status FROM boleto WHERE idevento = 1"; + Statement statement = conexion.createStatement(); + ResultSet resultSet = statement.executeQuery(query); + + while (resultSet.next()) { + int seatId = resultSet.getInt("id_asiento"); + String status = resultSet.getString("status"); + seatStatus.put(seatId, status); + } + } catch (SQLException e) { + System.out.println("Error al cargar el estado de los asientos."); + e.printStackTrace(); + } + + return seatStatus; + } + + // Nuevo: Método para mostrar alertas + private void mostrarAlerta(String titulo, String encabezado, String contenido) { + Alert alert = new Alert(Alert.AlertType.WARNING); + alert.setTitle(titulo); + alert.setHeaderText(encabezado); + alert.setContentText(contenido); + alert.showAndWait(); + } + public static void main(String[] args) { launch(args); } -} +} \ No newline at end of file diff --git a/src/main/java/org/example/saladeconciertos/VentanaPago.java b/src/main/java/org/example/saladeconciertos/VentanaPago.java new file mode 100644 index 0000000..312a6b8 --- /dev/null +++ b/src/main/java/org/example/saladeconciertos/VentanaPago.java @@ -0,0 +1,119 @@ +package org.example.saladeconciertos; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import javafx.geometry.Insets; +import javafx.geometry.Pos; + +import java.sql.*; +import java.util.List; +import java.util.Map; + +public class VentanaPago { + private static final String DB_URL = "jdbc:mysql://sql10.freesqldatabase.com:3306/sql10766655"; + private static final String DB_USER = "sql10766655"; + private static final String DB_PASSWORD = "7BZbRjEkXZ"; + private VentaBoletos ventaBoletos; // Referencia a VentaBoletos + + public VentanaPago(VentaBoletos ventaBoletos) { + this.ventaBoletos = ventaBoletos; + } + + public void mostrarVentanaPago(List<Integer> selectedSeats, Map<Integer, Double> seatPrices, String eventName, String eventDate) { + Stage paymentStage = new Stage(); + paymentStage.setTitle("Pago de Boletos"); + + // Layout principal + VBox paymentLayout = new VBox(20); + paymentLayout.setPadding(new Insets(20)); + paymentLayout.getStyleClass().add("payment-window"); // Aplicar clase CSS + paymentLayout.setAlignment(Pos.CENTER); + + // Título de la ventana + Label titleLabel = new Label("Confirmar Compra"); + titleLabel.getStyleClass().add("title"); // Aplicar clase CSS + + // Detalles del evento + Label eventLabel = new Label("Evento: " + eventName); + Label dateLabel = new Label("Fecha: " + eventDate); + + // Calcular el precio total + double totalPrice = selectedSeats.stream().mapToInt(seat -> seat).mapToDouble(seatPrices::get).sum(); + Label totalLabel = new Label("Total a pagar: $" + String.format("%.2f", totalPrice)); + + // Campo para ingresar el nombre del cliente + TextField nameField = new TextField(); + nameField.setPromptText("Nombre del cliente"); + nameField.setMaxWidth(200); + + // Botón para confirmar el pago + Button payButton = new Button("Pagar"); + payButton.getStyleClass().add("button"); // Aplicar clase CSS + + payButton.setOnAction(e -> { + String clientName = nameField.getText(); + if (clientName.isEmpty()) { + mostrarAlerta("Advertencia", "Nombre del cliente vacío", "Por favor, ingrese el nombre del cliente."); + } else { + generarTicket(clientName, selectedSeats, seatPrices, eventName, eventDate, totalPrice); + paymentStage.close(); + + // Refrescar la interfaz de VentaBoletos después de cerrar la ventana de pago + ventaBoletos.refrescarInterfaz(); + } + }); + + // Agregar elementos al layout + paymentLayout.getChildren().addAll(titleLabel, eventLabel, dateLabel, totalLabel, new Label("Nombre del cliente:"), nameField, payButton); + + // Configurar la escena y mostrar la ventana + Scene paymentScene = new Scene(paymentLayout, 400, 300); + paymentScene.getStylesheets().add(getClass().getResource("/styles.css").toExternalForm()); // Aplicar CSS + paymentStage.setScene(paymentScene); + paymentStage.show(); + } + + private void generarTicket(String clientName, List<Integer> selectedSeats, Map<Integer, Double> seatPrices, String eventName, String eventDate, double totalPrice) { + StringBuilder ticketDetails = new StringBuilder(); + ticketDetails.append("Evento: ").append(eventName).append("\n"); + ticketDetails.append("Fecha: ").append(eventDate).append("\n"); + ticketDetails.append("Cliente: ").append(clientName).append("\n"); + ticketDetails.append("Asientos: "); + for (int seat : selectedSeats) { + ticketDetails.append(seat).append(" ($").append(String.format("%.2f", seatPrices.get(seat))).append("), "); + } + ticketDetails.append("\nTotal: $").append(String.format("%.2f", totalPrice)); + + mostrarAlerta("Ticket Generado", "Detalles del Ticket", ticketDetails.toString()); + + // Actualizar el estado de los boletos comprados en la base de datos + actualizarEstadoBoletos(selectedSeats, 1); // Cambia el idevento según corresponda + } + + private void actualizarEstadoBoletos(List<Integer> selectedSeats, int idevento) { + try (Connection conexion = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) { + String updateQuery = "UPDATE boleto SET status = 'vendido', fechaVenta = CURDATE() WHERE id_asiento = ? AND idevento = ?"; + PreparedStatement preparedStatement = conexion.prepareStatement(updateQuery); + + for (int seat : selectedSeats) { + preparedStatement.setInt(1, seat); + preparedStatement.setInt(2, idevento); + preparedStatement.executeUpdate(); + } + + System.out.println("Estado de los boletos actualizado correctamente."); + } catch (SQLException e) { + System.out.println("Error al actualizar el estado de los boletos."); + e.printStackTrace(); + } + } + + private void mostrarAlerta(String titulo, String encabezado, String contenido) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(titulo); + alert.setHeaderText(encabezado); + alert.setContentText(contenido); + alert.showAndWait(); + } +} \ No newline at end of file