+
    :mair                        R t ^ RIHtHtHt ^ RIHtHt ^ RIt^ RIt]P                  P                  ]P                  P                  ]P                  P                  ]P                  P                  ]P                  P                  ]P                  P                  ]4      4      4      4      4      4       ^ RIHt ^ RIHt  ! R R4      tR tR# )	uz  
Módulo de Solicitud de Vuelos.

Este módulo gestiona todo el flujo de creación de solicitudes de vuelo:
1. Obtención de catálogos (centros de costos)
2. Validación de datos básicos
3. Validación de centro de costos
4. Validación de proyecto (si existe)
5. Validación de reglas de negocio
6. Generación de folio
7. Inserción en base de datos
8. Respuesta al cliente
)jsonifyrender_templaterequest)datetimedateN)SolicitudVueloSQL)RulesValidatorc                   N   a  ] tR t^"t o RtR tR tR tR tR t	R t
R tR	tV tR
# )SolicitudVueloControlleru   
Controlador principal para el módulo de Solicitud de Vuelos.

Esta clase maneja toda la lógica de negocio para crear solicitudes de vuelo,
incluyendo validaciones, generación de folios e inserción en base de datos.
c                B    \        4       V n        \        4       V n        R# )zInicializa el controlador.N)r   sqlr   rules_validator)selfs   &fc:\Users\victor.cervantes\Desktop\Elep\src\App\Global_Module\AdminSolicitudes\Vuelos\SolicitudVuelo.py__init__!SolicitudVueloController.__init__*   s    $&-/    c                	    \        RD4       \        R4       \        RC4       \        R4       V P                  V4      pVR,          '       g%   \        RVR,           24       RRRR	RVR,          /# \        R
4       \        R4       VP                  R4      pV P                  P	                  V4      pVR,          '       g#   \        RVR,           24       RRRVR,          /# \        RVR,          R,           24       VP                  R4      pRpV'       d   VP                  4       '       d   \        RV R24       V P                  P                  V4      pVR,          '       g#   \        RVR,           24       RRRVR,          /# VR,          '       g   \        R4       RRRRV R2/# \        RVR,          R,           24       M\        R4       \        R4       V P                  V4      pVR,          '       g%   \        R VR,           24       RRRR!RVR,          /# \        R"4       \        R#4       V P                  V4      p	\        R$4       \        R%4       V P                  P                  V	4      p
V
R,          '       g%   \        R&V
R,           24       RRRR'RV
R,          /# V
R(,          pV
R),          p\        R*V R+V 24       \        R,4       VP                  R-. 4      pV'       dv   V P                  V4      pV P                  P                  W4      pVR,          '       g%   \        R.VR,           24       RRRR/RVR,          /# \        R0VR1,           24       M\        R24       \        R34       VP                  R4. 4      pV'       dw   V P                  V4      pV P                  P                  VV4      pVR,          '       g%   \        R5VR,           24       RRRR6RVR,          /# \        R7VR1,           24       M\        R84       \        RD4       \        R94       \        R:V 24       \        R;V 24       \        RE4       RR<RR=R)VR>VRR?\        V4      R@\        V4      //#   \         dG   p\        RA\!        T4       24       ^ RIpTP%                  4        RRRRBR\!        T4      /u Rp?# Rp?ii ; i)Fu  
🎯 FUNCIÓN ORQUESTADORA PRINCIPAL

Esta función coordina todo el flujo de creación de una solicitud de vuelo.

FLUJO DE EJECUCIÓN:
1. Creación estructura de datos recibidos
2. Validar centro de costos (existe y está activo)
3. Validar proyecto en ERP (si se proporcionó)
4. Validar reglas de negocio (kilometraje, anticipación, etc.)
5. Generar folio único
6. Insertar solicitud principal
7. Insertar pasajeros
8. Insertar opciones de vuelo
9. Retornar respuesta exitosa con folio

Args:
    datos_json (dict): Diccionario con todos los datos de la solicitud (camelCase)
    
Returns:
    dict: Respuesta estructurada con success, mensaje, datos o errores
u.   🎯 INICIANDO CREACIÓN DE SOLICITUD DE VUELOu.   
📋 PASO 1: Validando estructura de datos...validou   ❌ Estructura inválida: erroressuccessFmensajeu   Datos incompletos o inválidosu   ✅ Estructura válidau+   
💰 PASO 2: Validando centro de costos...centroCostosexisteu    ❌ Centro de costos inválido: erroru   ✅ Centro de costos válido: datos
NombreCeCoproyectoNu"   
📁 PASO 3: Validando proyecto 'z' en ERP...u   ❌ Proyecto inválido: vigenteu   ❌ Proyecto no vigentezEl proyecto "u   " no está vigente en el ERPu   ✅ Proyecto válido: NombreProyectou5   
ℹ️  PASO 3: Sin proyecto especificado (opcional)u,   
📏 PASO 4: Validando reglas de negocio...u$   ❌ Reglas de negocio no cumplidas: z#No se cumplen las reglas de negociou)   ✅ Todas las reglas de negocio cumplidasu1   
📦 PASO 5: Preparando datos para inserción...u   ✅ Datos preparadosu/   
💾 PASO 6: Insertando solicitud principal...u!   ❌ Error al insertar solicitud: zError al guardar la solicitudflight_request_idfoliou   ✅ Solicitud insertada - ID: z	, Folio: u%   
👥 PASO 7: Insertando pasajeros...	pasajerosu!   ❌ Error al insertar pasajeros: zError al guardar pasajerosu   ✅ Pasajeros insertados: 
insertadosu#   ℹ️  Sin pasajeros para insertaru0   
✈️  PASO 8: Insertando opciones de vuelo...vuelosu   ❌ Error al insertar vuelos: z"Error al guardar opciones de vuelou   ✅ Vuelos insertados: u+   ℹ️  Sin opciones de vuelo para insertaru+   🎉 SOLICITUD DE VUELO CREADA EXITOSAMENTEu   📄 Folio: u	   🆔 ID: Tz&Solicitud de vuelo creada exitosamenteflightRequestIdpasajerosInsertadosvuelosInsertadosu   
❌ ERROR CRÍTICO: Error al procesar la solicitudP================================================================================Q
================================================================================zQ================================================================================
)print_validar_estructura_datosgetr   validar_centro_costosstripvalidar_proyecto_erp_validar_reglas_negocio_preparar_datos_solicitudinsertar_solicitud_preparar_pasajerosinsertar_pasajeros_preparar_vuelosinsertar_vueloslen	Exceptionstr	traceback	print_exc)r   
datos_jsonvalidacion_estructuracentro_costosresultado_ccr   vigencia_proyectoresultado_proyectovalidacion_reglasdatos_solicitudresultado_insertr    r!   r"   pasajeros_preparadosresultado_pasajerosr$   vuelos_preparadosresultado_vueloser;   s   &&                   r   crear_solicitud_vuelo.SolicitudVueloController.crear_solicitud_vuelo3   s2   .l	- BC&M
 CD$($B$B:$N!(2223H3S2TUVu?4Y? 
 *+
 @A&NN>:M8899-HL))8g9N8OPQu|G4  2<3H3V2WXY
 "~~j1H $HNN,,;H:[QR%)XX%B%B8%L")(3345G5P4QRS!5!#5g#> 
 *)4434!5!]8*<X#Y 
 ./A'/JK[/\.]^_NO
 AB $ < <Z H$X..<=Ny=Y<Z[\uD0; 
 =>
 FG"<<ZHO()
 DE#xx::?K#I..9:J7:S9TUVu>-g6  !11D E$W-E23D2EYugVW
 :;"{B7I'+'?'?	'J$&*hh&A&ABS&j#*955=>QRY>Z=[\]!5!#?!4W!= 
 23F|3T2UVW;<
 EF^^Hb1F$($9$9&$A!#'88#;#;<MO`#a '	22:;KG;T:UVW!5!#G!1'!: 
 /0@0N/OPQCD
 - ?@L()I/012-  4C!#4)3y>&F	 	  		*3q6(34! 5;Q 		sh   A/R  2A2R  %AR  2AR  R  R  1A6R  (B
R  3B&R  BR  #R   A?R   S;SSSc                   . p. ROpV F-  pWA9  g   W,          '       d   K  VP                  RV 24       K/  	  RV9   dA   VR,          pRR.pV F-  pWE9  g   WT,          '       d   K  VP                  RV 24       K/  	  RV9   dF   \        VR,          \        4      '       d   \        VR,          4      ^ 8X  d   VP                  R4       RV9   dm   \        VR,          \        4      '       g   VP                  R	4       MN\        VR,          4      ^8  d&   VP                  R
\        VR,          4       R24       MVP                  R4       R\        V4      ^ 8H  RV/# )u   
Valida que los datos recibidos tengan la estructura mínima requerida.

Args:
    datos (dict): Datos del frontend en camelCase
    
Returns:
    dict: {'valido': bool, 'errores': list}
fechasr"   zCampo obligatorio faltante: salida
horaSalidaz%Campo de fecha obligatorio faltante: Debe haber al menos un pasajeror$   z"El campo vuelos debe ser una listau5   Se requieren mínimo 3 opciones de vuelo (recibidas: )zEl campo vuelos es obligatorior   r   )r   descripcionorigendestinorN   r"   )append
isinstancelistr8   )r   r   r   campos_obligatorioscamporN   campos_fecha_obligatorioss   &&     r   r,   2SolicitudVueloController._validar_estructura_datos   sL    
 j(E!!=eWEF ) u8_F *2<(@%2&fmmNN%J5'#RS 3 %eK0$773u[?Q;RVW;W@A
 ueHot44CDU8_%)!VWZ[`ai[jWkVllmnoNN;< c'la'w
 	
r   c                N   . p VP                  R/ 4      pVP                  R4      pV'       g   VP                  R4       RRRV/# \        P                  ! VR4      P	                  4       pVP                  R4      pR	pV'       d=   \        P                  ! VR4      P	                  4       pWu8  d   VP                  R
4       \        P
                  ! 4       pWX8  d   VP                  R4       WX,
          P                  p	V	^8  d   \        RV	 R24       TP                  R/ 4      pT'       d\    TP                  RR4      pRT9   dB   \        TP                  RR4      P                  RR4      4      pT^d8  d   \        RT R24       TP                  R. 4      p\        T4      ^ 8X  d   TP                  R4       TP                  R. 4      p\        T4      ^8  d   TP                  R\        T4       R24       R\        T4      ^ 8H  RT/#   \         d)   p
TP                  R\        T
4       24        R	p
?
EL(R	p
?
i\         d)   p
TP                  R\        T
4       24        R	p
?
ELYR	p
?
ii ; i  \         d#   p
\        R\        T
4       24        R	p
?
ELR	p
?
ii ; i)u  
Valida las reglas de negocio específicas para solicitudes de vuelo.

Por ejemplo:
- Kilometraje mínimo para requerir vuelo
- Anticipación mínima
- Equipaje máximo

Args:
    datos (dict): Datos de la solicitud en camelCase
    
Returns:
    dict: {'valido': bool, 'errores': list}
rN   rO   z!La fecha de salida es obligatoriar   Fr   z%Y-%m-%dregresoNz>La fecha de regreso no puede ser anterior a la fecha de salidaz,La fecha de salida no puede ser en el pasadou+   ⚠️  ADVERTENCIA: Anticipación de solo u    días (recomendado: 7+ días)zError en formato de fecha: zError al validar fechas: 
distancias	carretera0 kmkm km ,u+   ⚠️  ADVERTENCIA: Kilometraje muy bajo (z km)u(   ⚠️  No se pudo validar kilometraje: r"   rQ   r$   u2   Se requieren mínimo 3 opciones de vuelo (actual: rR   )r-   rV   r   strptimer   todaydaysr+   
ValueErrorr:   r9   floatreplacer8   )r   r   r   rN   fecha_salida_strfecha_salidafecha_regreso_strfecha_regresohoydias_anticipacionrJ   r_   kilometraje_strkilometrajer"   r$   s   &&              r   r1   0SolicitudVueloController._validar_reglas_negocio9  s}    
(	AYYx,F  &zz(3#BC %G<<#,,-=zJOOQL !'

9 5 M  ( 1 12CZ P U U W !/NN#cd **,C!MN
 ".!3 9 9 1$CDUCVVtuv YY|R0

K",..f"E?*"'(?(?r(J(R(RSVXZ(["\K #S( KK=X\]^ IIk2.	y>QNN<=
 8R(v;?NNOPSTZP[}\]^_ c'la'w
 	
I  	CNN8QABB 	ANN6s1vh?@@	A"  K@QIJJKsT   *H H ?H BH 1AI7 I4H>>I4I4I//I47J$JJ$c                   VP                  R/ 4      pVP                  R/ 4      p\        V\        4      '       d   VP                  RR4      M
\        V4      pVP                  R/ 4      p\        V\        4      '       d   VP                  RR4      M
\        V4      pVP                  R/ 4      pVP                  RR4      pR	V9   d,   \	        VP                  R
R4      P                  RR4      4      MRp	RVP                  R4      RVP                  R4      RRRVP                  R4      RVRV	RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RR /# )!u   
Prepara los datos de la solicitud principal para inserción en BD.
Convierte de camelCase (frontend) a formato SQL.

Args:
    datos (dict): Datos del frontend en camelCase
    
Returns:
    dict: Datos preparados para SQL
rN   rT   namerd   rU   r_   r`   ra   rb   rc   re   g        CentroCostosr   Proyector   VigenciaProyectoNDescripcionMotivorS   DestinoKilometrajeViajeFechaSalidarO   FechaRegresor^   HoraAproxSalidarP   HoraAproxRegresohoraRegreso	CreatedBySYSTEM)r-   rW   dictr:   rj   rk   )
r   r   rN   
origen_obj
origen_strdestino_objdestino_strr_   rr   rs   s
   &&        r   r2   2SolicitudVueloController._preparar_datos_solicitud  sU    8R( YYx,
3=j$3O3OZ^^FB/UXYcUd
 ii	2.5?T5R5Rkoofb1X[\gXh YY|R0
$..f=TX\kTkeO33E2>FFsBOPqt EIIn5		*-=!9{6::h/FJJy1vzz,7

= 9
 	
r   c                B   . p\        V^R7       EF
  w  r4/ RVP                  R4      bRVP                  R4      bRVP                  R4      bRVP                  R	4      bR
VP                  RR4      bRVP                  R4      bRRbRVP                  R4      bRVP                  R4      bRVP                  R4      bRRbRRbRRbRRbRRbRRbRVP                  RR4      bRVP                  R 4      R!VP                  R"4      R#V/CpVP                  V4       EK  	  V# )$u   
Prepara los datos de pasajeros para inserción en BD.
Convierte de camelCase (frontend) a formato SQL.

Args:
    lista_pasajeros (list): Lista de pasajeros del frontend en camelCase
    
Returns:
    list: Lista de pasajeros preparados para SQL
startNombrePasajeronombreCompletoNumeroEmpleadonumeroEmpleadoEmpresaempresaFechaNacimientofechaNacimientoTipoIdentificacionidentificacionOficialINENumeroIdentificacionVigenciaIdentificacionNNacionalidadnacionalidadCorreoElectronicoemailTelefonotelefonoNumeroPasaporteVigenciaPasaporteTieneVisaVigenteFTipoVisaVigenciaVisaPaisVisaRequiereEquipajeExtrarequiereEquipajeCantidadMaletascantidadMaletasExcesoEquipajeKgexcesoEquipajeOrdenPasajero)	enumerater-   rV   )r   lista_pasajerosrF   idxpasajeropasajero_preparados   &&    r   r4   ,SolicitudVueloController._preparar_pasajeros  s     "&a@@MC" (,,/?"@" (,,/?"@" 8<<	2" "8<<0A#B	"
 %hll3JE&R" '5L(M" )$" ^ <" $X\\'%:" HLL4" "4" $T" #E" D" "  D!"" (6H%)P#"$ "8<<0A#B"HLL1A$B)", !''(:;/ A2 $#r   c                    . p\        V^R7       FY  w  r4RVP                  R4      RVP                  R4      RRR\        VP                  R	^ 4      4      R
V/pVP                  V4       K[  	  V# )u   
Prepara los datos de opciones de vuelo para inserción en BD.
Convierte de camelCase (frontend) a formato SQL.

Args:
    lista_vuelos (list): Lista de vuelos del frontend en camelCase
    
Returns:
    list: Lista de vuelos preparados para SQL
r   	Aerolinea	aerolineaNumeroVuelonumeroVuelo
FechaVueloN
CostoTotal
costoTotalOrdenPreferencia)r   r-   rj   rV   )r   lista_vuelosrH   r   vuelovuelo_preparados   &&    r   r6   )SolicitudVueloController._preparar_vuelos  sw     #L:JCUYY{3uyy7deEIIlA$>?"CO $$_5 ; ! r   )r   r   N)__name__
__module____qualname____firstlineno____doc__r   rK   r,   r1   r2   r4   r6   __static_attributes____classdictcell__)__classdict__s   @r   r
   r
   "   s9     0CR;
z`
L&
P&$P! !r   r
   c                  a \        4       oV P                  RR.R7      R 4       pV P                  RR.R7      V3R l4       pV P                  RR.R7      R 4       pV P                  R	R
.R7      V3R l4       p\        R4       R# )u   
Registra las rutas de Flask para el módulo de Solicitud de Vuelos.

Args:
    app: Instancia de Flask
    mail: Instancia de Flask-Mail (para envío de correos si es necesario)
z./Global/AdminSolicitudes/Vuelos/SolicitudVueloGET)methodsc                     \        R4      # )u^   
Renderiza la página HTML del módulo de Solicitud de Vuelos.

Returns:
    HTML renderizado
z2Global/AdminSolicitudes/Vuelos/SolicitudVuelo.html)r    r   r   solicitud_vuelo_page6ejecutar_solicitud_vuelo.<locals>.solicitud_vuelo_page  s     STTr   z=/Global/AdminSolicitudes/Vuelos/SolicitudVuelo/centros-costosc                   <  \        R4       SP                  P                  4       p V R,          '       d7   \        R\        V R,          4       24       \	        RRRV R,          /4      ^3# \        RV R,           24       \	        RRR	R
RV R,          /4      R3#   \
         dR   p\        R\        T4       24       ^ RIpTP                  4        \	        RRR	R
R\        T4      /4      R3u Rp?# Rp?ii ; i)zn
Endpoint para obtener todos los centros de costos activos.

Returns:
    JSON con lista de centros de costos
u;   
📥 GET /centros-costos - Obteniendo centros de costos...r   u!   ✅ Centros de costos obtenidos: centrosTu   ❌ Error: r   Fr   z"Error al obtener centros de costos  u   ❌ ERROR EN ENDPOINT: N)	r+   r   obtener_centros_costosr8   r   r9   r:   r;   r<   )	resultadorJ   r;   
controllers      r   r   8ejecutar_solicitud_vuelo.<locals>.obtener_centros_costos+  s!   	PQ"==?I##9#i	>R:S9TUVty3    
 Ig$6#789uCYw/   	   		+CF845!5?Q  	 		s)   3B 5B -.B C8'AC3-C83C8z3/Global/AdminSolicitudes/Vuelos/SolicitudVuelo/testc                 t    \        RRRRR\        P                  ! 4       P                  R4      RRR	R
RR/4      # )uo   
Ruta de prueba para verificar que el backend funciona correctamente.

Returns:
    JSON con mensaje de éxito
r   Tr   u;   ¡Backend de Solicitud de Vuelos funcionando correctamente!	timestampz%Y-%m-%d %H:%M:%SmodulozSolicitud de Vuelosversionz1.0axios_ready)r   r   nowstrftimer   r   r   test_solicitud_vuelo6ejecutar_solicitud_vuelo.<locals>.test_solicitud_vueloU  sH     tT001DE+u4
  	r   z4/Global/AdminSolicitudes/Vuelos/SolicitudVuelo/crearPOSTc                   <  \        R4       \        R4       \        R4       \        P                  ! 4       p V '       g   \        R4       \        RRRR/4      R3# \        R4       \        R	V P	                  R
4       24       \        RV P	                  RR4       24       \        R\        V P	                  R. 4      4       24       \        R\        V P	                  R. 4      4       24       SP                  V 4      pVR,          '       d   ^MRp\        V4      V3#   \         dR   p\        R\        T4       24       ^ RI	pTP                  4        \        RRRRR\        T4      /4      R3u Rp?# Rp?ii ; i)u   
Endpoint para crear una nueva solicitud de vuelo.

Recibe JSON con toda la información de la solicitud en camelCase y ejecuta
el flujo completo de validación e inserción.

Returns:
    JSON con resultado de la operación
u%   📥 RECIBIENDO PETICIÓN POST /crearu(   ❌ No se recibieron datos en el requestr   Fr   zNo se recibieron datosi  u!   ✅ Datos recibidos correctamenteu   📊 Centro de Costos: r   u   📊 Proyecto: r   zN/Au   📊 Pasajeros: r"   u   📊 Vuelos: r$   u   
❌ ERROR EN ENDPOINT: Nr(   r   r   r)   r*   )r+   r   get_jsonr   r-   r8   rK   r9   r:   r;   r<   )r=   r   status_coderJ   r;   r   s        r   crear_solicitud_vuelo_endpoint@ejecutar_solicitud_vuelo.<locals>.crear_solicitud_vuelo_endpointj  s|   &	- 9:&M !))+J@Au7    
 57+JNN>,J+KLMOJNN:u$E#FGH$SR)H%I$JKLM#jnnXr&B"C!DEF #88DI "+9!5!5#3K9%{22 		-c!fX67!5;Q  	 		s&   AD" CD" "E>-AE93E>9E>u9   ✅ Rutas de Solicitud de Vuelo registradas correctamenteN)r
   router+   )appmailr   r   r   r   r   s   &&    @r   ejecutar_solicitud_vuelor     s     *+J 	YY?%YQU RU 	YYNY^X_Y`# a#R 	YYDugYV W( 	YYEPVxYX0 Y0d 

EFr   )r   flaskr   r   r   r   r   sysospathrV   dirnameabspath__file__>Consultas_SQL.Global.AdminSolicitudes.Vuelos.SolicitudVueloSQLr    App.Utilities_module.RulesGlobalr   r
   r   r   r   r   <module>r      s    4 3 # 
 	 PRPWPWP_P_`hPi@j0k lm n \ <d! d!VPGr   