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