From 4d91e64c2e1622c2cffe224bc4d5edeae7d99806 Mon Sep 17 00:00:00 2001
From: "Luis.Aguilar" <aguilar.luiseder27@gmail.com>
Date: Sun, 9 Mar 2025 14:51:34 -0600
Subject: [PATCH] Agregue las opciones de pago y el generador de pdf

---
 src/main/java/module-info.java                |   1 +
 .../saladeconciertos/PDFGenerator.java        |  59 ++++++++++++++++++
 .../example/saladeconciertos/VentanaPago.java |  15 ++---
 src/main/resources/qrcode.png                 | Bin 0 -> 703 bytes
 4 files changed, 68 insertions(+), 7 deletions(-)
 create mode 100644 src/main/java/org/example/saladeconciertos/PDFGenerator.java
 create mode 100644 src/main/resources/qrcode.png

diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index e005d0b..bec50b9 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -2,6 +2,7 @@ module org.example.saladeconciertos {
     requires javafx.controls;
     requires javafx.fxml;
     requires java.sql;
+    requires org.apache.pdfbox;
 
 
     opens org.example.saladeconciertos to javafx.fxml;
diff --git a/src/main/java/org/example/saladeconciertos/PDFGenerator.java b/src/main/java/org/example/saladeconciertos/PDFGenerator.java
new file mode 100644
index 0000000..dba32d8
--- /dev/null
+++ b/src/main/java/org/example/saladeconciertos/PDFGenerator.java
@@ -0,0 +1,59 @@
+package org.example.saladeconciertos;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
+
+import java.io.File;
+import java.io.IOException;
+
+public class PDFGenerator {
+
+    public static void generarPDF(String eventName, String eventDate, String clientName, double totalPrice, String qrImagePath) {
+        // Ruta donde se guardará el PDF
+        String downloadsPath = System.getProperty("user.home") + "/Downloads/";
+        String fileName = "Ticket_" + eventName.replace(" ", "_") + ".pdf";
+        String pdfPath = downloadsPath + fileName;
+
+        try (PDDocument document = new PDDocument()) {
+            // Crear una nueva página
+            PDPage page = new PDPage();
+            document.addPage(page);
+
+            // Crear un flujo de contenido para la página
+            try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
+                // Configurar la fuente y el tamaño (usando Standard14Fonts)
+                PDType1Font font = new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD);
+                contentStream.setFont(font, 12);
+
+                // Escribir los detalles del ticket
+                contentStream.beginText();
+                contentStream.newLineAtOffset(50, 700);
+                contentStream.showText("Evento: " + eventName);
+                contentStream.newLineAtOffset(0, -20);
+                contentStream.showText("Fecha: " + eventDate);
+                contentStream.newLineAtOffset(0, -20);
+                contentStream.showText("Cliente: " + clientName);
+                contentStream.newLineAtOffset(0, -20);
+                contentStream.showText("Total: $" + String.format("%.2f", totalPrice));
+                contentStream.endText();
+
+                // Agregar la imagen del código QR (si existe)
+                if (qrImagePath != null && !qrImagePath.isEmpty()) {
+                    PDImageXObject qrImage = PDImageXObject.createFromFile(qrImagePath, document);
+                    contentStream.drawImage(qrImage, 50, 500, 150, 150); // Ajusta la posición y el tamaño de la imagen
+                }
+            }
+
+            // Guardar el PDF en la carpeta de descargas
+            document.save(pdfPath);
+            System.out.println("Ticket generado y guardado en: " + pdfPath);
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.out.println("Error al generar el PDF del ticket.");
+        }
+    }
+}
\ 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
index c7a2741..e407ea9 100644
--- a/src/main/java/org/example/saladeconciertos/VentanaPago.java
+++ b/src/main/java/org/example/saladeconciertos/VentanaPago.java
@@ -8,11 +8,9 @@ import javafx.geometry.Insets;
 import javafx.geometry.Pos;
 import javafx.scene.layout.Priority;
 import javafx.scene.layout.Region;
-
 import java.sql.*;
 import java.util.List;
 import java.util.Map;
-import java.util.regex.Pattern;
 
 public class VentanaPago {
     private static final String DB_URL = "jdbc:mysql://sql10.freesqldatabase.com:3306/sql10766655";
@@ -156,8 +154,8 @@ public class VentanaPago {
 
         // Envolver el layout en un ScrollPane
         ScrollPane scrollPane = new ScrollPane(paymentLayout);
-        scrollPane.setFitToWidth(true);
-        scrollPane.setFitToHeight(true);
+        scrollPane.setFitToWidth(true); // Ajustar el ancho del contenido al ScrollPane
+        scrollPane.setFitToHeight(true); // Ajustar la altura del contenido al ScrollPane
 
         // Configurar la escena y mostrar la ventana
         Scene paymentScene = new Scene(scrollPane, 400, 450);
@@ -166,19 +164,18 @@ public class VentanaPago {
         paymentStage.show();
     }
 
-    // Método para validar tarjeta
     private boolean validarTarjeta(String cardNumber, String expiryDate, String cvv) {
         return cardNumber.matches("\\d{13}") && // 13 dígitos
                 expiryDate.matches("(0[1-9]|1[0-2])/[0-9]{2}") && // MM/YY
                 cvv.matches("\\d{3}"); // 3 dígitos
     }
 
-    // Método para validar email
     private boolean validarEmail(String email) {
-        return Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)$").matcher(email).matches();
+        return email.matches("^[A-Za-z0-9+_.-]+@(.+)$"); // Validación básica de correo
     }
 
     private void generarTicket(String clientName, List<Integer> selectedSeats, Map<Integer, Double> seatPrices, String eventName, String eventDate, double totalPrice) {
+        // Mostrar el ticket en una ventana (como antes)
         StringBuilder ticketDetails = new StringBuilder();
         ticketDetails.append("Evento: ").append(eventName).append("\n");
         ticketDetails.append("Fecha: ").append(eventDate).append("\n");
@@ -191,6 +188,10 @@ public class VentanaPago {
 
         mostrarAlerta("Ticket Generado", "Detalles del Ticket", ticketDetails.toString());
 
+        // Generar el PDF del ticket usando la clase PDFGenerator
+        String qrImagePath = "src/main/resources/qrcode.png"; // Cambia esto por la ruta de tu imagen QR
+        PDFGenerator.generarPDF(eventName, eventDate, clientName, totalPrice, qrImagePath);
+
         // Actualizar el estado de los boletos comprados en la base de datos
         actualizarEstadoBoletos(selectedSeats, 1); // Cambia el idevento según corresponda
     }
diff --git a/src/main/resources/qrcode.png b/src/main/resources/qrcode.png
new file mode 100644
index 0000000000000000000000000000000000000000..f795880625efd78aad13d36dd5ee21b006353309
GIT binary patch
literal 703
zcmV;w0zmzVP)<h;3K|Lk000e1NJLTq00AZd00AZe0{{R3^$M?<00006P)t-s|Ns90
z0033O(|!N|010qNS#tmY4#WTe4#WYKD-Ig~00Li0L_t(&f$dpQuEZb+B=G<q$*X&$
z9>By0Gw8bQJHSFpn%$<19|FRFBCovi$}h<@>GRUpR`j=a{VlUgHN{AQvj5ukw_Hs%
zs>h->YIkh{RGs>P8a2i+13-_DnNaTAI_;C%1C~gJ8q(AfFoub)kW47sddGusz8X*M
ze{mlb#mr>JxIfSQ6&1Aw-^|-;iH9;a%3@i?!rAorVlRfRM}>)vvf5%csI)|5X0l9t
zS|T(G!E5oW#;{aGl;vQ-!A*ctQ9rA`@c6<2s4#OU<LD?Dz&2fwhfqjCg>Ghuj3ThW
z)q>2#WQ+hmQ&eaa^dt+juM#@lFey;O&nSEg#>f0r7zHU%6HUoBhA%P#D0F@TlrS@0
zZWVNytgA8}**7Rkcdx-){Kz&0vbow`>cQM2qu|&^RH4t=SmW$U3KYuAWRVdl>FQ#2
zbz34f3Iw+CA?Yhvw+?OwlyBOIEvF!pBcF07Oo36G&vIJ8DCVi1pH?h53LO}zK?gNx
ztfDZ+#}c7Y>_vS3;ZAPg@?Y6EII43biK&mdTJ@_tksK)hMxy7uugj;jW<YUt2Ocyr
zD)5mrTb7XmRTe!*Gu?SN!a3zxheD&ghi1|RU)cQp`_zU;dD--F2-2`%4kQOJ436p~
zcbHH%@^_9&jvIsED2U~!dC)!h`Hbk$DDIeL6a6$%xYo;p8gMuZCK&E9$-CbVg+;AR
z55JE^f9cl<sZfK1N%3xMtjU2SLdhE1VMs|cw1>CDqC|EGuXVPlT=KYWj*429q>=8e
l%aHb6USgwOdF7SgkUvnkiw7geAOrva002ovPDHLkV1n5yKw1C*

literal 0
HcmV?d00001