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