- 
                Notifications
    You must be signed in to change notification settings 
- Fork 0
services

La Capa de Servicios (services) es un componente fundamental del sistema Capybara Films, responsable de encapsular la lógica de negocio central y orquestar los flujos de trabajo clave de la aplicación. Actúa como un intermediario vital entre la interfaz de usuario y la capa de acceso a datos, asegurando que las operaciones se realicen de manera consistente y validada.
Dentro de esta capa, se distinguen dos clases principales que colaboran para ofrecer una funcionalidad robusta:
- 
CineServices: Orquesta el proceso completo de reserva de cine, gestionando las interacciones con el usuario y aplicando las reglas de negocio principales. 
- 
ServicioValidacion: Se encarga de la validación exhaustiva de los datos de entrada del usuario y la gestión del ciclo de vida de los clientes (búsqueda y registro). 
A continuación, se detalla la arquitectura, funcionalidades y responsabilidades de cada uno de estos servicios.
La clase CineServices es el orquestador principal de las operaciones del cine. Sus responsabilidades clave incluyen:
- Orquestación del Flujo de Reserva: Coordina todos los pasos del proceso de reserva, desde la selección de la película hasta la finalización.
- Gestión de Interacciones con el Usuario: Maneja las entradas y salidas en la consola, guiando al usuario a través del proceso.
- Aplicación de Reglas de Negocio: Asegura que todas las operaciones cumplan con las reglas definidas del negocio (ej., butacas disponibles, validación de datos).
- Coordinación de Componentes: Interactúa con los servicios de validación y los objetos de acceso a datos (DAOs) para ejecutar las operaciones.
| Método | Descripción | 
|---|---|
| verificar_y_validar_cliente() | Verifica si el cliente existe o lo registra manualmente. | 
| elegir_pelicula() | Muestra películas disponibles y permite elegir una. | 
| seleccionar_sala_y_entradas() | Muestra salas disponibles y solicita cantidad de entradas. | 
| seleccionar_butacas() | Permite seleccionar butacas para las entradas compradas. | 
| mostrar_matriz_butacas() | Visualiza la disposición de butacas en una sala. | 
| seleccionar_combos() | Muestra el menú de combos y permite seleccionar varios. | 
| solicitar_cantidad_entradas() | Pregunta al usuario cuántas entradas desea comprar. | 
| butaca_esta_disponible() | Verifica si una butaca está libre o ocupada. | 
| get_butaca() | Retorna una butaca según su ubicación (fila y columna). | 
| _solicitar_ubicacion() | Solicita una fila y columna para ubicar la butaca. | 
| obtener_precio_por_categoria() | Retorna el precio de una butaca según su categoría. | 
| limpiar_pantalla() | Limpia la pantalla de la consola para mejorar la experiencia visual. | 
CineServices actúa como el orquestador principal del sistema de reservas de cine, coordinando la interacción entre el usuario y todas las capas del sistema. Esta clase centraliza la lógica de negocio del proceso de reserva, delegando operaciones específicas de datos a los DAOs correspondientes y aplicando validaciones a través de ServicioValidacion.
La clase maneja el flujo completo desde la verificación del cliente hasta la selección de butacas y combos, integrando múltiples componentes del sistema de manera cohesiva.
graph TD
    subgraph Capa de Servicios
        CS[CineServices]
        SV[ServicioValidacion]
    end
    subgraph Capa de Acceso a Datos
        ClienteDAO[ClienteDAO]
        PeliculaDAO[PeliculaDAO]
        SalaDAO[SalaDAO]
        ButacaDAO[ButacaDAO]
        CandyDAO[CandyDAO]
    end
    subgraph Entidades de Dominio
        Cliente[Cliente]
        Pelicula[Pelicula]
        Sala[Sala]
        Butaca[Butaca]
        Ubicacion[Ubicacion]
        TipoCandy[TipoCandy]
        TipoButaca[TipoButaca]
    end
    CS --> SV
    CS --> ClienteDAO
    CS --> PeliculaDAO
    CS --> SalaDAO
    CS --> ButacaDAO
    CS --> CandyDAO
    ClienteDAO --> Cliente
    PeliculaDAO --> Pelicula
    SalaDAO --> Sala
    ButacaDAO --> Butaca
    ButacaDAO --> Ubicacion
    ButacaDAO --> TipoButaca
    CandyDAO --> TipoCandy
    El flujo de trabajo de verificación del cliente maneja tanto el inicio de sesión de clientes existentes como el registro de nuevos clientes a través de un proceso integrado. El método verificar_y_validar_cliente() implementa este proceso integral con validación de DNI, búsqueda de clientes existentes y registro guiado que incluye validación de nombre, apellido y correo electrónico.
graph TD
    A[Usuario ingresa DNI] --> B{**¿DNI válido?** <br/> 8 dígitos numéricos <br> CineServices};
    B -- No --> C[❌ **Mostrar error** <br/> Pedir DNI nuevamente];
    C --> A;
    B -- Si --> D[🔎 **Buscar cliente en BD** <br> ClienteDAO <br> buscar_por_dni];
    D --> E{**¿Cliente existe?**};
    E -- Si --> F[😍 **Mostrar bienvenida** <br/> Retornar cliente];
    E -- No --> G{**¿Desea registrarse?**};
    G -- No --> H[💔 **Terminar proceso** <br> return None];
    G -- Si --> I[📝 **Pedir nombre**];
    I --> J{**¿Nombre válido?** <br> ServicioValidacion <br> es_nombre_valido};
    J -- No --> K[❌ **Mostrar error**];
    K --> I;
    J -- Si --> L[📝 **Pedir apellido**];
    L --> M{**¿Apellido válido?** <br> ServicioValidacion <br> es_nombre_valido};
    M -- No --> N[❌ **Mostrar error**];
    N --> L;
    M -- Si --> O[📧 **Pedir email**];
    O --> P{**¿Email válido?** <br/> CineServices <br> Contiene @ y .};
    P -- No --> Q[❌ **Mostrar error**];
    Q --> O;
    P -- Si --> R[💾 **Crear cliente en BD** <br> ClienteDAO <br> crear_cliente];
    R --> S[**Verificar creación exitos**a <br> ClienteDAO <br> buscar_por_dni];
    S --> T[🎉 **Registro exitoso** <br/> return cliente_creado];
    - 
Validación de DNI: Se realiza directamente en CineServices usando dni.isdigit()y verificación de longitud.
- 
Validación de nombres: Utiliza ServicioValidacion.es_nombre_valido()para nombres y apellidos.
- Validación de email: Implementa verificación básica de '@' y '.' en CineServices.
- Verificación post-creación: Confirma el registro exitoso buscando nuevamente el cliente.
El proceso de selección de película se integra con la disponibilidad de salas y la gestión de capacidad para asegurar opciones de reserva viables.
| Método | Propósito | Validaciones Clave | 
|---|---|---|
| elegir_pelicula() | Muestra las películas disponibles y maneja la selección. | Validación de rango, manejo de errores, verificación de lista vacía. | 
| seleccionar_sala_y_entradas() | Asocia salas con películas y valida la capacidad. | Disponibilidad de butacas, límites de cantidad, validación de salas existentes. | 
| solicitar_cantidad_entradas() | Obtiene la cantidad de entradas deseada del usuario. | Validación numérica usando ServicioValidacion.es_numero(), números positivos. | 
Importante: El método seleccionar_sala_y_entradas() no utiliza solicitar_cantidad_entradas() como método separado. En su lugar, solicita directamente la cantidad de entradas usando input()
El flujo completo en main.py muestra cómo estos métodos se integran:
- 
Selección de Película: main.py:49-53- Retorna objeto Peliculaseleccionada
- Validación de selección exitosa antes de continuar
 
- Retorna objeto 
- 
Selección de Sala y Entradas: main.py:56-60- Usa la película para buscar salas disponibles.
- Retorna tupla (sala, cantidad_entradas).
- Validación de disponibilidad antes del siguiente paso.
 
- Manejo de listas vacías: Verificación implícita en el bucle de enumeración
- 
Validación de índices: cine_services.py:121-124
- Manejo de errores de entrada: Captura de ValueError para entradas no numéricas
- 
Verificación de disponibilidad de butacas: cine_services.py:141-146
- 
Validación de cantidad positiva: Verifica que cantidad_entradas > 0
- 
Límites de capacidad: Compara con cantidad_butacas_disponibles
- 
Validación numérica: cine_services.py:35
- 
Números positivos: Validación de cantidad > 0
El subsistema de selección de butacas proporciona una representación visual de la disposición de la sala y una reserva interactiva de butacas.
graph TD
    subgraph Datos de Dependencia
        BDAO[ButacaDAO]
        Sala[Sala]
        Butaca[Butaca]
        Ubicacion[Ubicacion]
        TipoButaca[TipoButaca]
    end
    subgraph Métodos de Apoyo
        MMB[mostrar_matriz_butacas]
        SUB[_solicitar_ubicacion]
        BDP[butaca_esta_disponible]
        GB[get_butaca]
        OPPC[obtener_precio_por_categoria]
    end
    subgraph Proceso de Selección de Butacas
        SSB[seleccionar_butacas]
    end
    SSB --> MMB
    SSB --> SUB
    SSB --> BDP
    SSB --> GB
    SSB --> OPPC
    MMB -- "requiere" --> BDAO
    MMB -- "requiere" --> Sala
    MMB -- "requiere" --> Butaca
    MMB -- "requiere" --> Ubicacion
    MMB -- "requiere" --> TipoButaca
    SUB -- "usa" --> MMB
    BDP -- "usa" --> Butaca
    GB -- "usa" --> Butaca
    OPPC -- "usa" --> TipoButaca
    El flujo de trabajo de selección de butacas combina la visualización de la matriz con la selección interactiva de posiciones, la verificación de disponibilidad y las actualizaciones del estado de la base de datos para las butacas reservadas.
El método mostrar_matriz_butacas() crea una representación en cuadrícula de 12x12 de la disposición de los asientos de la sala que incluye:
- Filas premium: Las filas 6, 7 y 8 se marcan como premium con "P"
- Escaleras visuales: Se insertan entre las columnas 3-4 y 9-10 para realismo
- Estados visuales: "X" para ocupadas, "P" para premium disponibles, " " para comunes disponibles
 🎥🎭  Buscando sala...  
  
 🪑🎬   Seleccione su butaca:   
  
Las filas 6, 7 y 8 son premium ⭐⭐⭐  
  
1	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
  
2	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
  
3	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
  
4	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
  
5	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
  
6	[P] [P] [P] Escalera  [P] [P] [P] [P] [P] Escalera  [P] [P]   
  
7	[P] [P] [P] Escalera  [P] [P] [P] [P] [P] Escalera  [P] [P]   
  
8	[P] [P] [P] Escalera  [P] [P] [P] [P] [P] Escalera  [P] [P]   
  
9	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
  
10	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
  
11	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
  
12	[ ] [ ] [ ] Escalera  [ ] [ ] [ ] [ ] [ ] Escalera  [ ] [ ]   
El método seleccionar_butacas() implementa un bucle iterativo completo:
- 
Visualización inicial: mostrar_matriz_butacas()renderiza el estado actual de la sala
- 
Solicitud de ubicación: _solicitar_ubicacion()valida coordenadas (1-12 para fila y columna)cine_services.py:155-169
- 
Verificación de disponibilidad: butaca_esta_disponible()yget_butaca()confirman el estadocine_services.py:171-176
- 
Actualización de estado: ButacaDAO.actualizar_estado()persiste la reservacine_services.py:206-207
- 
Repetición: El proceso se repite para cada entrada solicitada 
El método obtener_precio_por_categoria() usa el enum TipoButaca para determinar precios dinámicamente:
- Butacas comunes: $4,000
- Butacas premium: $6,500
El sistema de selección de combos proporciona un menú interactivo para la compra de productos de confitería utilizando definiciones de productos basadas en enumeraciones.
graph TD
    subgraph Flujo de Selección de Combos
        SC[seleccionar_combos]
    end
    SC --> TDC[TipoCandy enum]
    SC --> CD[CandyDAO]
    SC --> DM[Mostrar menú]
    DM --> UI[Entrada de usuario]
    UI --> VI[Validar entrada]
    VI --> AS[Añadir selección]
    AS --> RL{Repetir bucle?}
    RL -- "Sí" --> DM
    RL -- "No" --> Fin[Fin]
    El método seleccionar_combos() itera a través de los valores del enumerado TipoCandy para mostrar las opciones disponibles con sus precios, manejando selecciones múltiples y la validación de entrada.
El sistema utiliza el enum TipoCandy que define tres categorías de combos:
- CHICO: Combo Chico = 🍿 Pochoclo chico + 🥤 bebida 500cc - 5,000.
- MEDIANO: Combo Mediano = 🍿 Pochoclo mediano + 2 🥤 bebidas 500cc - 8,000.
- GRANDE: Combo Grande = 🍿 Pochoclo grande + 4 🥤 bebidas 500cc - 10,000.
El método implementa un bucle interactivo completo que incluye:
- 
Mostrar menú: Enumera todos los combos disponibles con precios usando enumerate(TipoCandy, start=1).
- Entrada de usuario: Acepta selección numérica (0 para terminar).
- Validación: Verifica rango válido y maneja errores de entrada.
- Confirmación: Muestra combo agregado y limpia pantalla.
- Repetición: Permite seleccionar múltiples combos hasta que el usuario elija salir.
- 
Rango numérico: Verifica que la opción esté entre 0 y len(TipoCandy)
- Manejo de ValueError: Captura entradas no numéricas con mensajes de error descriptivos
- Opción de salida: Permite terminar el proceso seleccionando 0
El método se integra en el flujo principal del sistema como paso opcional después de la selección de butacas:
Los combos seleccionados se asocian directamente al objeto Reserva y se incluyen en el cálculo del precio total y el resumen final de la compra.
La clase CineServices se integra con múltiples objetos de acceso a datos (DAOs) para realizar operaciones de negocio complejas.
| DAO | Métodos que lo Utilizan en CineServices | Propósito | 
|---|---|---|
| ClienteDAO | verificar_y_validar_cliente() | Búsqueda y creación de clientes. | 
| PeliculaDAO | elegir_pelicula() | Acceso al catálogo de películas. | 
| SalaDAO | seleccionar_sala_y_entradas() | Asociaciones sala-película. | 
| ButacaDAO | mostrar_matriz_butacas(),seleccionar_butacas() | Gestión de butacas y actualizaciones de estado. | 
| CandyDAO | seleccionar_combos() | Inventario de productos de confitería. | 
La capa de servicio gestiona los cambios de estado de las entidades, particularmente para las reservas de butacas:
# Patrón de actualización del estado de la butaca desde seleccionar_butacas()
butaca_seleccionada.set_estado(False)
butaca_dao.actualizar_estado(butaca_seleccionada.id_butaca, False)Este patrón asegura que tanto el estado del objeto en memoria como la persistencia en la base de datos permanezcan sincronizados durante el proceso de reserva.
El sistema implementa operaciones complejas que requieren coordinación entre múltiples DAOs:
Ejemplo: Creación de Reserva
- 
ReservaDAOcolabora conButacaDAOyClienteDAOpara construir objetos completos.
- Maneja transacciones que involucran múltiples tablas (reservaydetalle_reserva)
- Construye entidades complejas agregando datos de diferentes fuentes
La capa de datos implementa validación antes de la persistencia:
- 
ClienteDAOintegraServicioValidacionpara validar nombres antes de crear clientes.
- Verificación de duplicados de DNI antes de inserción
- Validación en múltiples capas del sistema para garantizar integridad de datos
El sistema implementa manejo robusto de errores a través de todas las capas:
- Captura de excepciones específicas (psycopg2.Error,ValueError).
- Propagación controlada de errores desde DAOs hacia servicios.
- Mensajes de error contextualizados para diferentes tipos de fallas.
- Recuperación graceful ante fallos de base de datos.
El flujo principal demuestra la integración completa:
- 
Entrada: Datos del usuario → CineServices
- 
Procesamiento: CineServices→ múltiples DAOs
- Persistencia: DAOs → Base de datos
- Construcción: DAOs → Entidades de dominio
- Salida: Entidades → Presentación al usuario
El sistema usa un patrón consistente de inyección de dependencias:
- Instanciación centralizada de DatabaseConnection.
- Inyección de conexión a todos los DAOs.
- Paso de DAOs como parámetros a métodos de servicio.
- Gestión unificada del ciclo de vida de las conexiones.
La clase ServicioValidacion es una biblioteca de utilidades de validación que proporciona métodos estáticos para garantizar la integridad de datos en el sistema Capybara Films. Sus responsabilidades clave incluyen:
- Validación de Entrada de Usuario: Proporciona métodos estáticos reutilizables para validar datos de entrada.
- Normalización Unicode: Maneja caracteres especiales y acentos para validación consistente.
- 
Integración con Servicios: Actúa como biblioteca compartida utilizada por CineServicesy DAOs.
| Método | Tipo | Descripción | 
|---|---|---|
| __init__() | Instancia | Inicializa conexión a base de datos y ClienteDAOcon manejo de errores. | 
| es_numero(cadena) | Estático | Verifica si una cadena contiene solo dígitos numéricos. | 
| es_nombre_valido(cadena) | Estático | Valida nombres con normalización Unicode y verificación alfabética. | 
ServicioValidacion actúa como una biblioteca de utilidades que se integra con múltiples componentes del sistema. Su valor principal reside en sus métodos estáticos de validación.
graph TD
    subgraph Servicios que utilizan ServicioValidacion
        CineServices
        ClienteDAO
    end
    subgraph Métodos de ServicioValidacion
        es_numero
        es_nombre_valido
    end
    subgraph Tipos de Validación
        Entradas_Numericas
        Nombres_Apellidos
    end
    CineServices --> es_numero
    CineServices --> es_nombre_valido
    ClienteDAO --> es_nombre_valido
    es_numero --> Entradas_Numericas
    es_nombre_valido --> Nombres_Apellidos
    - 
Método Nativo: Utiliza str.isdigit()de Python.
- Retorno Booleano: True para cadenas que contienen solo dígitos, False en caso contrario.
- Simplicidad: Implementación directa sin validaciones adicionales.
El método se utiliza en CineServices para validar entradas de cantidad: cine_services.py:35
- Verificación de Tipo: Valida que la entrada sea string y no esté vacía.
- 
Normalización Unicode: Usa unicodedata.normalize('NFKC', cadena)para manejar acentos y caracteres especiales.
- Eliminación de Espacios: Permite espacios en nombres pero los elimina para validación.
- 
Validación Alfabética: Verifica que solo contenga letras usando isalpha().
- 
En CineServicespara validación durante registro:cine_services.py:251
- 
En ClienteDAOpara validación previa a persistencia:ClienteDAO.py:13-18
ServicioValidacion se integra como biblioteca de utilidades en el flujo principal de CineServices:
- 
Validación de DNI: Realizada directamente en CineServices(8 dígitos numéricos)
- 
Validación de Nombres: Utiliza ServicioValidacion.es_nombre_valido()para nombre y apellido
- 
Validación de Email: Implementada directamente en CineServices(contiene@y.):cine_services.py:266-267
graph TD
    A[Usuario ingresa nombre] --> B{CineServices valida con ServicioValidacion}
    B --> C{¿Nombre válido?}
    C -- No --> D[Mostrar error al usuario]
    D --> A
    C -- Sí --> E[ClienteDAO crea cliente]
    E --> F[Se guarda en base de datos]
    F --> G[Cliente registrado exitosamente]
    - 
Conexión a Base de Datos: Establece DatabaseConnectionpara acceso futuro.
- 
Inicialización de DAO: Crea instancia de ClienteDAOcon la conexión establecida.
- Manejo de Errores: Captura excepciones durante la inicialización.
- Logging de Errores: Proporciona mensajes descriptivos para resolución de problemas.
💾 Repositorio: Capybara Films en GitHub
© 2025 Capybara Films — Desarrollado por Carpinchos Programando
- 🏗️ Arquitectura del Sistema
- 📄 main.py
- 📁 data/
- 📁 daos/
- 📁 domain/entities/
- 📁 domain/entities/types
- 📁 services/
- ⚙️ Cómo Instalar y Ejecutar el Proyecto
- 🛠️ Cómo contribuir
- 🧪 Probar el Sistema Paso a Paso
- 🐞 Errores Comunes y Soluciones