From 7cc2cc206d7aa57fe7960a303077de10e88b260a Mon Sep 17 00:00:00 2001
From: "victor.monge" <zs22016120@estudiantes.uv.mx>
Date: Sun, 9 Mar 2025 16:17:55 -0600
Subject: [PATCH] =?UTF-8?q?Registro=20de=20ventas=20y=20generaci=C3=B3n=20?=
 =?UTF-8?q?de=20comprobante?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ProyectoVentaBoletos/pom.xml                  |   5 +
 .../java/controller/GeneradorComprobante.java | 194 ++++++++++++++++++
 .../java/controller/MenuSalaController.java   |  76 ++++++-
 .../src/main/java/model/Asiento.java          |   9 +
 .../src/main/java/model/Boleto.java           |   7 +
 .../src/main/java/model/ModeloSQL.java        | 162 ++++++++++++---
 .../src/main/java/model/Venta.java            |  60 +++---
 .../src/main/java/view/MenuSala.java          |  45 +---
 8 files changed, 459 insertions(+), 99 deletions(-)
 create mode 100644 ProyectoVentaBoletos/src/main/java/controller/GeneradorComprobante.java

diff --git a/ProyectoVentaBoletos/pom.xml b/ProyectoVentaBoletos/pom.xml
index 1bb8632..f81e706 100644
--- a/ProyectoVentaBoletos/pom.xml
+++ b/ProyectoVentaBoletos/pom.xml
@@ -22,5 +22,10 @@
             <artifactId>flatlaf</artifactId>
             <version>3.4.1</version>
         </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13.3</version>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/ProyectoVentaBoletos/src/main/java/controller/GeneradorComprobante.java b/ProyectoVentaBoletos/src/main/java/controller/GeneradorComprobante.java
new file mode 100644
index 0000000..e9d858d
--- /dev/null
+++ b/ProyectoVentaBoletos/src/main/java/controller/GeneradorComprobante.java
@@ -0,0 +1,194 @@
+package controller;
+
+import com.itextpdf.text.Document;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.Font;
+import com.itextpdf.text.FontFactory;
+import com.itextpdf.text.Paragraph;
+import com.itextpdf.text.Phrase;
+import com.itextpdf.text.pdf.PdfPCell;
+import com.itextpdf.text.pdf.PdfPTable;
+import com.itextpdf.text.pdf.PdfWriter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Date;
+import model.Asiento;
+import model.Boleto;
+import model.Evento;
+import model.ModeloSQL;
+import model.Venta;
+
+public class GeneradorComprobante {
+    private static final String RUTA_COMPROBANTES = "C:\\Users\\vmonge\\Desktop\\";
+    
+    // Fuentes para el documento
+    private static final Font TITULO_FONT = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 16);
+    private static final Font SUBTITULO_FONT = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12);
+    private static final Font TEXTO_NORMAL = FontFactory.getFont(FontFactory.HELVETICA, 10);
+    private static final Font TEXTO_NEGRITA = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 10);
+    
+    /**
+     * Genera un comprobante PDF para una venta de boletos
+     * 
+     * @param idVenta ID de la venta
+     * @param evento Información del evento
+     * @param boletos Lista de boletos vendidos
+     * @param fechaVenta Fecha en que se realizó la venta
+     * @param montoTotal Monto total de la venta
+     * @return Ruta del archivo PDF generado
+     */
+    public static String generarComprobantePDF(Venta venta, Evento evento, ArrayList<Boleto> boletos) {
+        // Nombre del archivo
+        String rutaArchivo = RUTA_COMPROBANTES + "comprobante_venta_" + venta.getIdVenta() + ".pdf";
+        
+        // Crear documento
+        Document documento = new Document();
+        
+        try {
+            // Inicializar escritor PDF
+            PdfWriter.getInstance(documento, new FileOutputStream(rutaArchivo));
+            documento.open();
+            
+            // Añadir encabezado
+            addEncabezado(documento, evento, venta.getIdVenta(), venta.getFechaVenta());
+            
+            // Añadir detalles de boletos
+            addDetalleBoletos(documento, boletos, venta.getIdVenta());
+            
+            // Añadir resumen de venta
+            addResumenVenta(documento, boletos.size(), venta.getTotalMonto());
+            
+            documento.close();
+            
+            return rutaArchivo;
+            
+        } catch (DocumentException | IOException e) {
+            System.out.println("[X] util.ComprobanteGenerator.generarComprobantePDF(): error " + e);
+            return null;
+        }
+    }
+    
+    /**
+     * Añade el encabezado al documento PDF
+     */
+private static void addEncabezado(Document documento, Evento evento, int idVenta, LocalDateTime fechaVenta) throws DocumentException {
+    // Título principal
+    Paragraph titulo = new Paragraph("COMPROBANTE DE VENTA", TITULO_FONT);
+    titulo.setAlignment(Element.ALIGN_CENTER);
+    titulo.setSpacingAfter(15);
+    documento.add(titulo);
+    
+    // Información del evento
+    Paragraph infoEvento = new Paragraph("Evento: " + evento.getNombre(), SUBTITULO_FONT);
+    infoEvento.setAlignment(Element.ALIGN_CENTER);
+    documento.add(infoEvento);
+    
+    // Fecha del evento - Corregido para java.sql.Date
+    Paragraph fechaEvento = new Paragraph("Fecha del evento: " + evento.getFecha().toString(), TEXTO_NORMAL);
+    fechaEvento.setAlignment(Element.ALIGN_CENTER);
+    fechaEvento.setSpacingAfter(20);
+    documento.add(fechaEvento);
+    
+    // Detalles de la venta
+    Paragraph infoVenta = new Paragraph("Información de la venta", SUBTITULO_FONT);
+    infoVenta.setSpacingAfter(10);
+    documento.add(infoVenta);
+    
+    // Tabla con detalles de venta
+    PdfPTable tablaInfoVenta = new PdfPTable(2);
+    tablaInfoVenta.setWidthPercentage(100);
+    tablaInfoVenta.setSpacingAfter(20);
+    
+    tablaInfoVenta.addCell(createCell("ID Venta:", true));
+    tablaInfoVenta.addCell(createCell(String.valueOf(idVenta), false));
+    
+    // Corregido para LocalDateTime
+    tablaInfoVenta.addCell(createCell("Fecha de venta:", true));
+    tablaInfoVenta.addCell(createCell(fechaVenta.format(java.time.format.DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")), false));
+    
+    float[] anchosTablaInfoVenta = {0.4f, 0.6f};
+    tablaInfoVenta.setWidths(anchosTablaInfoVenta);
+    documento.add(tablaInfoVenta);
+}
+    
+    /**
+     * Añade la tabla con el detalle de los boletos
+     */
+    private static void addDetalleBoletos(Document documento, ArrayList<Boleto> boletos, int idVenta) throws DocumentException {
+        Paragraph tituloBoletos = new Paragraph("Detalle de boletos", SUBTITULO_FONT);
+        tituloBoletos.setSpacingAfter(10);
+        documento.add(tituloBoletos);
+        // Tabla de boletos
+        PdfPTable tablaBoletos = new PdfPTable(4);
+        tablaBoletos.setWidthPercentage(100);
+        tablaBoletos.setSpacingAfter(20);
+        
+        // Encabezados de la tabla
+        tablaBoletos.addCell(createCell("ID Boleto", true));
+        tablaBoletos.addCell(createCell("Fila", true));
+        tablaBoletos.addCell(createCell("Número", true));
+        tablaBoletos.addCell(createCell("Costo", true));
+        
+        // Detalles de cada boleto
+        ModeloSQL modeloSQL = new ModeloSQL();
+        ArrayList<Asiento> asientos = modeloSQL.obtenerAsientosAsociadosVenta(idVenta);
+        
+        for (Boleto boleto : boletos) {
+            tablaBoletos.addCell(createCell(String.valueOf(boleto.getIdBoleto()), false));
+            
+            for(Asiento a: asientos){
+                if(boleto.getIdAsiento() == a.getIdAsiento()){
+                    tablaBoletos.addCell(createCell(a.getFila(), false));
+                    tablaBoletos.addCell(createCell(String.valueOf(a.getNumero()), false));
+                }
+            }
+            
+            tablaBoletos.addCell(createCell("$" + String.format("%.2f", boleto.getPrecio()), false));
+        }
+        
+        documento.add(tablaBoletos);
+    }
+    
+    /**
+     * Añade el resumen de la venta
+     */
+    private static void addResumenVenta(Document documento, int numeroBoletos, double montoTotal) throws DocumentException {
+        Paragraph tituloResumen = new Paragraph("Resumen", SUBTITULO_FONT);
+        tituloResumen.setSpacingAfter(10);
+        documento.add(tituloResumen);
+        
+        // Tabla resumen
+        PdfPTable tablaResumen = new PdfPTable(2);
+        tablaResumen.setWidthPercentage(100);
+        
+        tablaResumen.addCell(createCell("Número de boletos:", true));
+        tablaResumen.addCell(createCell(String.valueOf(numeroBoletos), false));
+        
+        tablaResumen.addCell(createCell("Monto total:", true));
+        tablaResumen.addCell(createCell("$" + String.format("%.2f", montoTotal), false));
+        
+        documento.add(tablaResumen);
+        
+        // Mensaje de agradecimiento
+        Paragraph agradecimiento = new Paragraph("¡Gracias por su compra!", TEXTO_NEGRITA);
+        agradecimiento.setAlignment(Element.ALIGN_CENTER);
+        agradecimiento.setSpacingBefore(30);
+        
+        float[] anchosTablaResumen = {0.7f, 0.3f};
+        tablaResumen.setWidths(anchosTablaResumen);
+        documento.add(agradecimiento);
+    }
+    
+    /**
+     * Crea una celda para las tablas
+     */
+    private static PdfPCell createCell(String texto, boolean esEncabezado) {
+        PdfPCell celda = new PdfPCell(new Phrase(texto, esEncabezado ? TEXTO_NEGRITA : TEXTO_NORMAL));
+        celda.setPadding(5);
+        return celda;
+    }
+}
\ No newline at end of file
diff --git a/ProyectoVentaBoletos/src/main/java/controller/MenuSalaController.java b/ProyectoVentaBoletos/src/main/java/controller/MenuSalaController.java
index 6772a05..f50d7db 100644
--- a/ProyectoVentaBoletos/src/main/java/controller/MenuSalaController.java
+++ b/ProyectoVentaBoletos/src/main/java/controller/MenuSalaController.java
@@ -9,11 +9,16 @@ import java.awt.event.ItemListener;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Date;
+import javax.swing.JOptionPane;
 import javax.swing.JToggleButton;
 import javax.swing.SwingUtilities;
 import model.Asiento;
+import model.Boleto;
+import model.Evento;
 import view.MenuSala;
 import model.ModeloSQL;
+import model.Venta;
 
 public class MenuSalaController implements ActionListener, ItemListener{
     private int idEvento;
@@ -52,7 +57,7 @@ public class MenuSalaController implements ActionListener, ItemListener{
                 int numero = rs.getInt("numero");
                 String estado = rs.getString("estado");
                 
-                Asiento asiento = new Asiento(idEvento, fila, numero);// Crear objeto asiento
+                Asiento asiento = new Asiento(idAsiento, fila, numero);// Crear objeto asiento
                 
                 JToggleButton botonAsiento = new JToggleButton(fila + ""+ numero + " ("+estado+")");// Crear botón
                 botonAsiento.setBounds(ejeX, ejeY, largoBoton, anchoBoton);// Establecer posición del botón
@@ -96,6 +101,8 @@ public class MenuSalaController implements ActionListener, ItemListener{
         // Si se presiono el boton para seleccionar asientos para una venta
         if(o.equals(menuSala.jButtonSeleccionarAsientosVenta)){
             if (!clickAsientosHabilitado){// Si la selección de asientos está bloqueada
+                arrayListAsientosSeleccionados = null;
+                arrayListAsientosSeleccionados = new ArrayList<>();
                 clickAsientosHabilitado = true;// Permitir la selección de asientos
                 menuSala.jButtonRealizarVenta.setEnabled(true);
                 menuSala.jPanelBotones.setBackground(Color.decode("#d7f1ce"));
@@ -114,9 +121,20 @@ public class MenuSalaController implements ActionListener, ItemListener{
         
         // Si se presiono el botón realizar venta
         if(o.equals(menuSala.jButtonRealizarVenta)){
-            // Verificar que se seleccionó por lo menos un asiento
+            // Verificar que se seleccionó por lo menos un asiento para realizar la venta
             if (!arrayListAsientosSeleccionados.isEmpty()) {
-
+                // Mostrar un diálogo de confirmación
+                int confirmacion = menuSala.confirmacion(arrayListAsientosSeleccionados.size());
+                // En función del dialogo de confirmación realizar o no la venta
+                if(confirmacion == JOptionPane.OK_OPTION){
+                    realizarVenta(arrayListAsientosSeleccionados);
+                } else if(confirmacion == JOptionPane.CANCEL_OPTION){
+                    System.out.println("controller.MenuSalaController.actionPerformed(): se canceló la venta.");
+                    return;
+                } else if(confirmacion == JOptionPane.CLOSED_OPTION){
+                    System.out.println("controller.MenuSalaController.actionPerformed(): se cerró la confirmación y se canceló la venta.");
+                    return;
+                }
             } else {
                 menuSala.mensaje("No ha seleccionado ningún asiento.");
             }
@@ -147,7 +165,7 @@ public class MenuSalaController implements ActionListener, ItemListener{
             if (e.getStateChange() == ItemEvent.SELECTED) {
                 arrayListAsientosSeleccionados.add(botonAsiento);
                 System.out.println("controller.MenuSalaController.itemStateChanged(): " + asiento.getFila() + "" + asiento.getNumero() + " añadido a arrayListAsientosSeleccionados");
-                System.out.println("controller.MenuSalaController.itemStateChanged(): " + asiento.getFila() + asiento.getNumero() + " seleccionado.");
+                //System.out.println("controller.MenuSalaController.itemStateChanged(): " + asiento.getFila() + asiento.getNumero() + " seleccionado.");
                 botonAsiento.setBackground(Color.YELLOW);
                 botonAsiento.setForeground(Color.WHITE);
 
@@ -156,7 +174,7 @@ public class MenuSalaController implements ActionListener, ItemListener{
                     arrayListAsientosSeleccionados.remove(botonAsiento);
                     System.out.println("controller.MenuSalaController.itemStateChanged(): " + asiento.getFila() + "" + asiento.getNumero() + " eliminado de arrayListAsientosSeleccionados");
                 }
-                System.out.println("controller.MenuSalaController.itemStateChanged(): " + asiento.getFila() + asiento.getNumero() + " deseleccionado.");
+                //System.out.println("controller.MenuSalaController.itemStateChanged(): " + asiento.getFila() + asiento.getNumero() + " deseleccionado.");
                 botonAsiento.setBackground(Color.GREEN);
                 botonAsiento.setForeground(Color.BLACK);
             }
@@ -164,12 +182,60 @@ public class MenuSalaController implements ActionListener, ItemListener{
     }
     
     public void realizarVenta(ArrayList<JToggleButton> arrayBotones){
+        int precioPorBoleto = 60;
         ArrayList<Asiento> arrayAsientos = new ArrayList<>();
+        int idVenta = 0;
+        Double montoTotal = 0.0;
+        
         for(JToggleButton boton: arrayBotones){
             Asiento asiento = (Asiento) boton.getClientProperty("asiento");
             arrayAsientos.add(asiento);
+            montoTotal += precioPorBoleto;
         }
         
+        // public int registrarVenta(int idEvento, int totalBoletos, Double totalMonto)
+        idVenta = modeloSQL.registrarVenta(idEvento, arrayBotones.size(), montoTotal);
+        
+        // Si idVenta = 0, significa que no se registró la venta.
+        if(idVenta == 0){
+            System.out.println("[X] controller.MenuSalaController.realizarVenta(): error al registrar venta.");
+            return;
+        }
+        
+        // Registrar y asociar boletos a la venta
+        for (Asiento asiento: arrayAsientos){
+            // void registrarBoleto(int idEvento, int idAsiento, double precio, int idVenta)
+            /*System.out.println("controller.MenuSalaController.realizarVenta():\n"
+                    + "\tregistrarBoleto(int idEvento, int idAsiento, double precio, int idVenta)\n"
+                    + "\tINSERT("+idEvento+","+asiento.getIdAsiento()+","+precioPorBoleto+","+idVenta+")");
+            */
+            modeloSQL.registrarBoleto(idEvento, asiento.getIdAsiento(), precioPorBoleto, idVenta);
+        }
+        
+        generarComprobante(idVenta);
+        
+        // Actualizar pantalla
+        menuSala.jPanelBotones.removeAll();
+        menuSala.revalidate();
+        menuSala.repaint();
+        obtenerAsientos(idEvento);
+        clickAsientosHabilitado = false;
+        menuSala.jButtonRealizarVenta.setEnabled(false);
+        menuSala.jPanelBotones.setBackground(Color.decode("#F6F6F6"));
+        menuSala.jButtonSeleccionarAsientosVenta.setBackground(Color.WHITE);
+        
+    }
+    
+    public void generarComprobante(int idVenta){
+        Venta venta = modeloSQL.obtenerVenta(idVenta);
+        if(venta == null){
+            return;
+        } else {
+            Evento evento = modeloSQL.obteneEvento(venta.getIdEvento());
+            ArrayList<Boleto> boletos = modeloSQL.obtenerBoletosVenta(idVenta);
+            GeneradorComprobante.generarComprobantePDF(venta, evento, boletos);
+        }
+
     }
     
 }
diff --git a/ProyectoVentaBoletos/src/main/java/model/Asiento.java b/ProyectoVentaBoletos/src/main/java/model/Asiento.java
index 99e0f08..9411dd8 100644
--- a/ProyectoVentaBoletos/src/main/java/model/Asiento.java
+++ b/ProyectoVentaBoletos/src/main/java/model/Asiento.java
@@ -18,6 +18,10 @@ public class Asiento {
     public void setNumero(int numero) {
         this.numero = numero;
     }
+
+    public void setIdAsiento(int idAsiento) {
+        this.idAsiento = idAsiento;
+    }
     
     public String getFila() {
         return fila;
@@ -26,5 +30,10 @@ public class Asiento {
     public int getNumero() {
         return numero;
     }
+
+    public int getIdAsiento() {
+        return idAsiento;
+    }
+    
     
 }
diff --git a/ProyectoVentaBoletos/src/main/java/model/Boleto.java b/ProyectoVentaBoletos/src/main/java/model/Boleto.java
index 8143128..01c79be 100644
--- a/ProyectoVentaBoletos/src/main/java/model/Boleto.java
+++ b/ProyectoVentaBoletos/src/main/java/model/Boleto.java
@@ -10,6 +10,13 @@ public class Boleto {
     private String estado;
     private Integer idVenta;
 
+    public Boleto(int idBoleto, int idEvento, int idAsiento, double precio, int idVenta){
+        this.idBoleto = idBoleto;
+        this.idEvento = idEvento;
+        this.idAsiento = idAsiento;
+        this.precio = precio;
+        this.idVenta = idVenta;
+    }
     public Boleto(int idEvento, int idAsiento, double precio) {
         this.idEvento = idEvento;
         this.idAsiento = idAsiento;
diff --git a/ProyectoVentaBoletos/src/main/java/model/ModeloSQL.java b/ProyectoVentaBoletos/src/main/java/model/ModeloSQL.java
index 8b0bb8a..e649af5 100644
--- a/ProyectoVentaBoletos/src/main/java/model/ModeloSQL.java
+++ b/ProyectoVentaBoletos/src/main/java/model/ModeloSQL.java
@@ -3,6 +3,9 @@ package model;
 import controller.ConexionSingleton;
 import java.sql.*;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 public class ModeloSQL {
     Connection con;
@@ -24,6 +27,30 @@ public class ModeloSQL {
         }
         return rs;
     }
+    public Evento obteneEvento(int idEvento) {
+        String query = "SELECT * FROM eventos WHERE idEvento = ?";
+        Evento evento = null;
+        
+        try {
+            PreparedStatement ps = con.prepareStatement(query);
+            ps.setInt(1, idEvento);
+            ResultSet rs = ps.executeQuery();
+            
+            if (rs.next()) {
+                String nombre = rs.getString("nombre");
+                Date fecha = rs.getDate("fecha");
+                
+                evento = new Evento(idEvento, nombre, fecha);
+            }
+            
+            rs.close();
+            ps.close();
+        } catch (SQLException ex) {
+            System.out.println("[X] model.ModeloSQL.obtenerInfoEvento(): error " + ex);
+        }
+        
+        return evento;
+    }
     
     // Asientos
     public ResultSet obtenerAsientosDisponibles(int idEvento){
@@ -41,21 +68,32 @@ public class ModeloSQL {
     }
     
     // Venta
-    public void registrarVenta(int idEvento, int totalBoletos, Double totalMonto){
+    public int registrarVenta(int idEvento, int totalBoletos, Double totalMonto){
+        int idVenta = 0;
         String sql = "INSERT INTO ventas (idEvento, fechaVenta, totalBoletos, totalMonto) VALUES (?, NOW(), ?, ?)";
         PreparedStatement pst = null;
         try {
-            pst = con.prepareStatement(sql);
+            pst = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
             pst.setInt(1, idEvento);
             pst.setInt(2, totalBoletos);
             pst.setDouble(3, totalMonto);
-            pst.executeUpdate();
+            int filasAfectadas = pst.executeUpdate();
+            // Obtener idVenta del insert para asociar boletos después
+            if(filasAfectadas > 0){
+                ResultSet generatedKeys = pst.getGeneratedKeys();
+                if( generatedKeys.next() ) {
+                    idVenta = generatedKeys.getInt(1);
+                    System.out.println("model.ModeloSQL.registrarVenta(): registro venta con id: " + idVenta);
+                }
+            }
             pst.close();
-            System.out.println("model.ModeloSQL.crearVenta(): venta registrada.");
+            //System.out.println("model.ModeloSQL.registrarVenta(): venta registrada.");
         } catch (SQLException ex) {
-            System.out.println("[X] model.ModeloSQL.crearVenta(): " + ex);
+            System.out.println("[X] model.ModeloSQL.registrarVenta(): " + ex);
         }
+        return idVenta;
     }
+    
     // Boleto
     public void registrarBoleto(int idEvento, int idAsiento, double precio, int idVenta){
         String sql = "INSERT INTO boletos (idEvento, idAsiento, precio, idVenta) VALUES (?, ?, ?, ?)";
@@ -70,32 +108,102 @@ public class ModeloSQL {
             pst.close();
             System.out.println("model.ModeloSQL.registrarBoleto(): boleto registrado.");
         } catch (SQLException ex) {
-            System.out.println("[X] model.ModeloSQL.registrarBoleto(): " + ex);
+            eliminarVenta(idVenta);
+            System.out.println("[X] model.ModeloSQL.registrarBoleto(): error al registrar boleto. " + ex);
+        }
+    }
+        public ArrayList<Boleto> obtenerBoletosVenta(int idVenta) {
+            ArrayList<Boleto> boletos = new ArrayList<>();
+            String sql = "SELECT b.idBoleto, b.idAsiento, a.fila, a.numero, b.precio, b.idVenta, b.idEvento " +
+                           "FROM boletos b JOIN asientos a ON b.idAsiento = a.idAsiento " +
+                           "WHERE b.idVenta = ?";
+            PreparedStatement pst = null;
+            try {
+                pst = con.prepareStatement(sql);
+                pst.setInt(1, idVenta);
+                ResultSet rs = pst.executeQuery();
+
+                while (rs.next()) {
+                    int idBoleto = rs.getInt("idBoleto");
+                    int idAsiento = rs.getInt("idAsiento");
+                    String fila = rs.getString("fila");
+                    int numero = rs.getInt("numero");
+                    double precio = rs.getDouble("precio");
+                    int idEvento = rs.getInt("idEvento");
+
+                    Boleto boleto = new Boleto(idBoleto, idEvento, idAsiento, precio, idVenta);
+                    boletos.add(boleto);
+                }
+
+                rs.close();
+                pst.close();
+            } catch (SQLException ex) {
+                System.out.println("[X] model.ModeloSQL.obtenerBoletosVenta(): error " + ex);
+            }
+
+            return boletos;
+        }
+    
+    public void eliminarVenta(int idVenta){
+        String sql = "DELETE FROM ventas WHERE idVenta=?";
+        PreparedStatement pst = null;
+        try {
+            pst = con.prepareStatement(sql);
+            pst.setInt(1, idVenta);
+            pst.executeUpdate();
+            Statement st = con.createStatement();
+            System.out.println("model.ModeloSQL.eliminarVenta(): venta id: "+idVenta+" eliminada.");
+        } catch (SQLException ex) {
+            System.out.println("model.ModeloSQL.eliminarVenta(): error a eliminar venta id: " + idVenta + ". " + ex);
         }
     }
     
-    
-    public ResultSet obtenerBoletosPorEvento(int idEvento){
-        ResultSet rs = null;
-        return rs;
+    public ArrayList<Asiento> obtenerAsientosAsociadosVenta(int idVenta){
+        ArrayList<Asiento> asientos = new ArrayList<>();
+        String sql = "SELECT a.idAsiento, a.fila, a.numero " +
+                      "FROM asientos a " +
+                      "INNER JOIN boletos b ON a.idAsiento = b.idAsiento " +
+                      "WHERE b.idVenta = ?";
+        PreparedStatement pst = null;
+        try{
+            pst = con.prepareStatement(sql);
+            pst.setInt(1, idVenta);
+            ResultSet rs = pst.executeQuery();
+                while (rs.next()) {
+                    int idAsiento = rs.getInt("idAsiento");
+                    String fila = rs.getString("fila");
+                    int numero = rs.getInt("numero");
+
+                    Asiento asiento = new Asiento(idAsiento, fila, numero);
+                    asientos.add(asiento);
+                }
+            rs.close();
+            pst.close();
+        } catch (SQLException ex) {
+            System.out.println("model.ModeloSQL.obtenerAsientosAsociadosVenta(): error " + ex);
+        }
+        return asientos;
     }
     
-    public boolean actualizarEstadoBoleto(int idBoleto, String nuevoEstado, LocalDateTime fechaVenta, Integer idVenta){
-        return true;
-    }
-    
-    public ResultSet getBoleto(int idEvento, int idAsiento){
-        ResultSet rs = null;
-        return rs;
-    }
-    
-    // Venta
-    public boolean registrarVenta(Venta venta){
-        return true;
-    }
-    
-    public ResultSet getVentasPorPeriodo(LocalDateTime inicio, LocalDateTime fin){
-        ResultSet rs = null;
-        return rs;
+    public Venta obtenerVenta(int idVenta){
+        String sql = "SELECT * FROM ventas WHERE idVenta = ?";
+        try {
+            PreparedStatement pst = con.prepareStatement(sql);
+            pst.setInt(1, idVenta);
+            ResultSet rs = pst.executeQuery();
+            if (rs.next()) {
+                Venta venta = new Venta();
+                venta.setIdVenta(rs.getInt("idVenta"));
+                venta.setIdEvento(rs.getInt("idEvento"));
+                venta.setFechaVenta(rs.getTimestamp("fechaVenta").toLocalDateTime());
+                venta.setTotalBoletos(rs.getInt("totalBoletos"));
+                venta.setTotalMonto(rs.getDouble("totalMonto"));
+                return venta;
+            }
+        } catch (SQLException ex) {
+            System.out.println("[X] model.ModeloSQL.obtenerVenta(): error " + ex);
+        }
+        System.out.println("[!] model.ModeloSQL.obtenerVenta(): no hay ninguna venta asociado a esa id.");
+        return null;
     }
 }
diff --git a/ProyectoVentaBoletos/src/main/java/model/Venta.java b/ProyectoVentaBoletos/src/main/java/model/Venta.java
index 0bbe764..9d3b476 100644
--- a/ProyectoVentaBoletos/src/main/java/model/Venta.java
+++ b/ProyectoVentaBoletos/src/main/java/model/Venta.java
@@ -2,7 +2,6 @@ package model;
 
 import java.time.LocalDateTime;
 import java.util.ArrayList;
-import java.util.List;
 import javax.swing.JToggleButton;
 
 public class Venta {
@@ -10,55 +9,52 @@ public class Venta {
     private int idEvento;
     private LocalDateTime fechaVenta;
     private int totalBoletos;
-    private int totalMonto;
-    private ArrayList<JToggleButton> asientosVenta;
-
-    public void setIdVenta(int idVenta) {
-        this.idVenta = idVenta;
-    }
-
-    public void setIdEvento(int idEvento) {
+    private double totalMonto;
+    
+    // Constructor vacío
+    public Venta() {}
+    
+    // Constructor con parámetros
+    public Venta(int idEvento, LocalDateTime fechaVenta, int totalBoletos, double totalMonto) {
         this.idEvento = idEvento;
-    }
-
-    public void setFechaVenta(LocalDateTime fechaVenta) {
         this.fechaVenta = fechaVenta;
-    }
-
-    public void setTotalBoletos(int totalBoletos) {
         this.totalBoletos = totalBoletos;
-    }
-
-    public void setTotalMonto(int totalMonto) {
         this.totalMonto = totalMonto;
     }
-
-    public void setAsientosVenta(ArrayList<JToggleButton> asientosVenta) {
-        this.asientosVenta = asientosVenta;
-    }
     
+    // Getters y Setters
     public int getIdVenta() {
         return idVenta;
     }
-
+    public void setIdVenta(int idVenta) {
+        this.idVenta = idVenta;
+    }
+    
     public int getIdEvento() {
         return idEvento;
     }
-
+    public void setIdEvento(int idEvento) {
+        this.idEvento = idEvento;
+    }
+    
     public LocalDateTime getFechaVenta() {
         return fechaVenta;
     }
-
+    public void setFechaVenta(LocalDateTime fechaVenta) {
+        this.fechaVenta = fechaVenta;
+    }
+    
     public int getTotalBoletos() {
         return totalBoletos;
     }
-
-    public int getTotalMonto() {
-        return totalMonto;
-    }
-
-    public ArrayList<JToggleButton> getAsientosVenta() {
-        return asientosVenta;
+    public void setTotalBoletos(int totalBoletos) {
+        this.totalBoletos = totalBoletos;
     }
     
+    public double getTotalMonto() {
+        return totalMonto;
+    }
+    public void setTotalMonto(double totalMonto) {
+        this.totalMonto = totalMonto;
+    }
 }
diff --git a/ProyectoVentaBoletos/src/main/java/view/MenuSala.java b/ProyectoVentaBoletos/src/main/java/view/MenuSala.java
index ce4e52d..73d3549 100644
--- a/ProyectoVentaBoletos/src/main/java/view/MenuSala.java
+++ b/ProyectoVentaBoletos/src/main/java/view/MenuSala.java
@@ -18,46 +18,11 @@ public class MenuSala extends javax.swing.JPanel {
         this.idEvento = idEvento;
         this.nombre = nombre;
         initComponents();
-        //asientos();
         MenuSalaController menuSalaController = new MenuSalaController(this);
         jButtonSeleccionarAsientosVenta.addActionListener(menuSalaController);
         jButtonRealizarVenta.addActionListener(menuSalaController);
     }
     
-    /*
-    private int filas = 6;
-    private int columnas = 7;
-    private int largoBoton = 140;
-    private int anchoBoton = 60;
-    private int ejeX = 20;
-    private int ejeY = 20;
-    public JToggleButton jtBotones[][];
-    private ArrayList<Boleto> boletosVendidos = new ArrayList<>();
-    int contadorNumeroAsientos = 0;
-    */
-    
-    /*
-    public void asientos(){
-        jtBotones = new JToggleButton[filas][columnas];
-        for(int i = 0; i < filas; i++){
-            for(int j = 0; j < columnas; j++){
-                jtBotones[i][j] = new JToggleButton();
-                contadorNumeroAsientos++;
-                jtBotones[i][j].setBounds(ejeX, ejeY, largoBoton, anchoBoton);
-                jtBotones[i][j].setText("Asiento: " + contadorNumeroAsientos);
-                jPanelBotones.add(jtBotones[i][j]);
-                ejeX += 160;
-                
-            }
-            
-            // Para que baje a la siguiente fila
-            ejeY += 70;
-            // Para que vuelva a construir la siguiente fila desde la posición X: 20
-            ejeX = 20;
-        }
-    }
-    */
-
     public int getIdEvento() {
         return idEvento;
     }
@@ -66,6 +31,16 @@ public class MenuSala extends javax.swing.JPanel {
         JOptionPane.showMessageDialog(this, mensaje);
     }
     
+    public int confirmacion(int numeroBoletos){
+        int opcion = JOptionPane.showConfirmDialog(
+                this,
+                "Realizar venta de " + numeroBoletos + " boletos.",
+                "Confirmación de venta",
+                JOptionPane.OK_CANCEL_OPTION
+        );
+        return opcion;
+    }
+    
     @SuppressWarnings("unchecked")
     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
     private void initComponents() {