diff --git a/clases/BaseDatos.php b/clases/BaseDatos.php
new file mode 100644
index 0000000..c27b5a1
--- /dev/null
+++ b/clases/BaseDatos.php
@@ -0,0 +1,94 @@
+<?php
+require_once 'Sala.php';
+require_once 'Boleto.php';
+require_once 'Venta.php';
+
+class BaseDatos {
+    private $conexion;
+    
+    public function __construct($host, $usuario, $password, $nombreBD) {
+        $this->conexion = new mysqli($host, $usuario, $password, $nombreBD);
+        
+        if ($this->conexion->connect_error) {
+            die("Error de conexión: " . $this->conexion->connect_error);
+        }
+    }
+    
+    public function cargarSala($idSala) {
+        $sala = null;
+        $query = "SELECT id, nombre FROM salas WHERE id = ?";
+        $stmt = $this->conexion->prepare($query);
+        $stmt->bind_param("i", $idSala);
+        $stmt->execute();
+        $result = $stmt->get_result();
+        
+        if ($fila = $result->fetch_assoc()) {
+            $sala = new Sala($fila['id'], $fila['nombre']);
+            
+            // Cargar boletos de la sala
+            $queryBoletos = "SELECT id, fila, numero, precio, estado FROM boletos WHERE id_sala = ?";
+            $stmtBoletos = $this->conexion->prepare($queryBoletos);
+            $stmtBoletos->bind_param("i", $idSala);
+            $stmtBoletos->execute();
+            $resultBoletos = $stmtBoletos->get_result();
+            
+            $boletos = [];
+            while ($filaBoleto = $resultBoletos->fetch_assoc()) {
+                $boleto = new Boleto($filaBoleto['id'], $filaBoleto['fila'], $filaBoleto['numero'], $filaBoleto['precio']);
+                if ($filaBoleto['estado'] === 'vendido') {
+                    $boleto->marcarComoVendido();
+                }
+                $boletos[] = $boleto;
+            }
+            
+            // Asignar boletos a la sala
+            $sala->setBoletos($boletos);
+        }
+        
+        return $sala;
+    }
+    
+    public function guardarVenta($venta) {
+        // Iniciar transacción
+        $this->conexion->begin_transaction();
+        
+        try {
+            // Insertar venta
+            $query = "INSERT INTO ventas (id, fecha, nombre_cliente, total) VALUES (?, ?, ?, ?)";
+            $stmt = $this->conexion->prepare($query);
+            $id = $venta->getId();
+            $fecha = $venta->getFecha();
+            $nombreCliente = $venta->getNombreCliente();
+            $total = $venta->getTotal();
+            $stmt->bind_param("sssd", $id, $fecha, $nombreCliente, $total);
+            $stmt->execute();
+            
+            // Actualizar estado de boletos
+            foreach ($venta->getBoletos() as $boleto) {
+                $queryBoleto = "UPDATE boletos SET estado = 'vendido' WHERE id = ?";
+                $stmtBoleto = $this->conexion->prepare($queryBoleto);
+                $idBoleto = $boleto->getId();
+                $stmtBoleto->bind_param("i", $idBoleto);
+                $stmtBoleto->execute();
+                
+                // Insertar relación venta-boleto
+                $queryRelacion = "INSERT INTO venta_boletos (id_venta, id_boleto) VALUES (?, ?)";
+                $stmtRelacion = $this->conexion->prepare($queryRelacion);
+                $stmtRelacion->bind_param("si", $id, $idBoleto);
+                $stmtRelacion->execute();
+            }
+            
+            // Confirmar transacción
+            $this->conexion->commit();
+            return true;
+        } catch (Exception $e) {
+            // Revertir transacción en caso de error
+            $this->conexion->rollback();
+            return false;
+        }
+    }
+    
+    public function cerrarConexion() {
+        $this->conexion->close();
+    }
+}
\ No newline at end of file
diff --git a/clases/Boleto.php b/clases/Boleto.php
new file mode 100644
index 0000000..bec7a82
--- /dev/null
+++ b/clases/Boleto.php
@@ -0,0 +1,46 @@
+<?php
+class Boleto {
+    private $id;
+    private $fila;
+    private $numero;
+    private $precio;
+    private $estado; // 'disponible' o 'vendido'
+    
+    public function __construct($id, $fila, $numero, $precio) {
+        $this->id = $id;
+        $this->fila = $fila;
+        $this->numero = $numero;
+        $this->precio = $precio;
+        $this->estado = 'disponible';
+    }
+    
+    // Getters y setters
+    public function getId() {
+        return $this->id;
+    }
+    
+    public function getFila() {
+        return $this->fila;
+    }
+    
+    public function getNumero() {
+        return $this->numero;
+    }
+    
+    public function getPrecio() {
+        return $this->precio;
+    }
+    
+    public function getEstado() {
+        return $this->estado;
+    }
+    
+    public function marcarComoVendido() {
+        $this->estado = 'vendido';
+        return true;
+    }
+    
+    public function estaDisponible() {
+        return $this->estado === 'disponible';
+    }
+}
\ No newline at end of file
diff --git a/clases/Sala.php b/clases/Sala.php
new file mode 100644
index 0000000..b1ea1af
--- /dev/null
+++ b/clases/Sala.php
@@ -0,0 +1,62 @@
+<?php
+require_once 'Boleto.php';
+
+class Sala {
+    private $id;
+    private $nombre;
+    private $boletos = [];
+    
+    public function __construct($id, $nombre) {
+        $this->id = $id;
+        $this->nombre = $nombre;
+    }
+    
+    public function getId() {
+        return $this->id;
+    }
+    
+    public function getNombre() {
+        return $this->nombre;
+    }
+    
+    public function inicializarBoletos($filas, $asientosPorFila, $precio) {
+        $this->boletos = [];
+        $contador = 1;
+        
+        for ($i = 1; $i <= $filas; $i++) {
+            for ($j = 1; $j <= $asientosPorFila; $j++) {
+                $this->boletos[] = new Boleto($contador, $i, $j, $precio);
+                $contador++;
+            }
+        }
+    }
+    
+    public function obtenerBoletos() {
+        return $this->boletos;
+    }
+    
+    public function obtenerBoletosPorEstado($estado) {
+        return array_filter($this->boletos, function($boleto) use ($estado) {
+            return $boleto->getEstado() === $estado;
+        });
+    }
+    
+    public function obtenerBoletosPorId($ids) {
+        return array_filter($this->boletos, function($boleto) use ($ids) {
+            return in_array($boleto->getId(), $ids);
+        });
+    }
+    
+    public function disponibilidadAsientos() {
+        $mapa = [];
+        foreach ($this->boletos as $boleto) {
+            $mapa[$boleto->getFila()][$boleto->getNumero()] = $boleto->getEstado();
+        }
+        return $mapa;
+    }
+    
+    // Setter para asignar boletos desde la base de datos
+    public function setBoletos($boletos) {
+        $this->boletos = $boletos;
+    }
+}
\ No newline at end of file
diff --git a/clases/VendedorController.php b/clases/VendedorController.php
new file mode 100644
index 0000000..b3b0393
--- /dev/null
+++ b/clases/VendedorController.php
@@ -0,0 +1,47 @@
+<?php
+require_once 'BaseDatos.php';
+require_once 'Sala.php';
+require_once 'Boleto.php';
+require_once 'Venta.php';
+
+class VendedorController {
+    private $baseDatos;
+    private $sala;
+    
+    public function __construct($baseDatos) {
+        $this->baseDatos = $baseDatos;
+    }
+    
+    public function cargarSala($idSala) {
+        $this->sala = $this->baseDatos->cargarSala($idSala);
+        return $this->sala;
+    }
+    
+    public function mostrarDisponibilidadAsientos() {
+        if ($this->sala) {
+            return $this->sala->disponibilidadAsientos();
+        }
+        return null;
+    }
+    
+    public function seleccionarBoletos($idsBoletos) {
+        if ($this->sala) {
+            return $this->sala->obtenerBoletosPorId($idsBoletos);
+        }
+        return [];
+    }
+    
+    public function procesarVenta($boletos, $nombreCliente) {
+        $venta = new Venta($nombreCliente);
+        $venta->agregarBoletos($boletos);
+        
+        if (count($venta->getBoletos()) > 0) {
+            $resultado = $this->baseDatos->guardarVenta($venta);
+            if ($resultado) {
+                return $venta->generarComprobante();
+            }
+        }
+        
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/clases/Venta.php b/clases/Venta.php
new file mode 100644
index 0000000..ccebad9
--- /dev/null
+++ b/clases/Venta.php
@@ -0,0 +1,68 @@
+<?php
+require_once 'Boleto.php';
+
+class Venta {
+    private $id;
+    private $fecha;
+    private $boletos = [];
+    private $total;
+    private $nombreCliente;
+    
+    public function __construct($nombreCliente) {
+        $this->id = uniqid();
+        $this->fecha = date('Y-m-d H:i:s');
+        $this->nombreCliente = $nombreCliente;
+        $this->total = 0;
+    }
+    
+    public function getId() {
+        return $this->id;
+    }
+    
+    public function getFecha() {
+        return $this->fecha;
+    }
+    
+    public function getNombreCliente() {
+        return $this->nombreCliente;
+    }
+    
+    public function agregarBoletos($boletos) {
+        foreach ($boletos as $boleto) {
+            if ($boleto->estaDisponible()) {
+                $this->boletos[] = $boleto;
+                $this->total += $boleto->getPrecio();
+                $boleto->marcarComoVendido();
+            }
+        }
+    }
+    
+    public function generarComprobante() {
+        $comprobante = [
+            'id_venta' => $this->id,
+            'fecha' => $this->fecha,
+            'cliente' => $this->nombreCliente,
+            'boletos' => [],
+            'total' => $this->total
+        ];
+        
+        foreach ($this->boletos as $boleto) {
+            $comprobante['boletos'][] = [
+                'id' => $boleto->getId(),
+                'fila' => $boleto->getFila(),
+                'numero' => $boleto->getNumero(),
+                'precio' => $boleto->getPrecio()
+            ];
+        }
+        
+        return $comprobante;
+    }
+    
+    public function getTotal() {
+        return $this->total;
+    }
+    
+    public function getBoletos() {
+        return $this->boletos;
+    }
+}
\ No newline at end of file