+
    iJ                         ^ RI t ^ RIt^ RIt^ RIHt ^ RIHt ^ RIHtHt ^ RI	H
t
Ht ^ RIHtHtHtHt ]P"                  ! ]P$                  R7       ]P&                  ! ]4      tRR ltR	 tR
 tR tR tRR ltR# )    N)current_user)datetime)current_apprender_template)MailMessage)obtener_destinatarios_mailvalidar_mail_list_existeguardar_log_envioobtener_subject_de_mail_list)levelc                ,   RRRRRR. R. R. R	^ /R
. R. RVRV R. RR/	p\         P                  ! 4       p V '       Eg   VR
,          P                  R4       RVR&   T\         P                  ! 4       p	\        W,
          4      VR&   VR,          '       d   \        P                  RV 24       M\        P                  RV 24        \        P                  p
 \        TTRP                  XP                  R. 4      4      RP                  VP                  R. 4      4      RP                  VP                  R. 4      4      T \        P                  ! V4      \        P                  ! VP                  R. 4      4      T
VR,          '       d   RMRVP                  R
4      '       d"   RP                  VP                  R
. 4      4      MRR7       # V'       Eg   V'       Ed   \        V4      pT;'       g    RpV'       g   VR,          P                  R4       MRpVR,          P                  R4       T\         P                  ! 4       p	\        W,
          4      VR&   VR,          '       d   \        P                  RV 24       M\        P                  RV 24        \        P                  p
 \        TTRP                  XP                  R. 4      4      RP                  VP                  R. 4      4      RP                  VP                  R. 4      4      T \        P                  ! V4      \        P                  ! VP                  R. 4      4      T
VR,          '       d   RMRVP                  R
4      '       d"   RP                  VP                  R
. 4      4      MRR7       # \         P"                  pT;'       g    / pT;'       g    . pT;'       g    / pT;'       g    / p\        P                  RV  24       R. R. R. /pV'       Ed   \        P                  R V 24       \%        V4      pVR,          '       Eg   VR
,          P                  R!VR,           24       R"VR&   T\         P                  ! 4       p	\        W,
          4      VR&   VR,          '       d   \        P                  RV 24       M\        P                  RV 24        \        P                  p
 \        TTRP                  VP                  R. 4      4      RP                  VP                  R. 4      4      RP                  VP                  R. 4      4      T \        P                  ! V4      \        P                  ! VP                  R. 4      4      T
VR,          '       d   RMRVP                  R
4      '       d"   RP                  VP                  R
. 4      4      MRR7       # VR#,          '       g7   VR,          P                  R$V R%24       \        P'                  R$V R&24       MVR',          '       g7   VR,          P                  R$V R(24       \        P'                  R$V R(24       M\)        V4      pVR,          '       d_   VR,          P+                  VR,          4       VR,          P+                  VR,          4       VR,          P+                  VR,          4       M"VR,          P                  R)VR,           24       V'       do   RE Fh  pVV9   g   K  VV,          '       g   K  VV,           F>  pV'       g   K  R*V9   g   K  VVV,          9  g   K&  VV,          P                  V4       K@  	  Kj  	  VR,          '       Eg4   V'       Eg   V'       Eg   VR
,          P                  R+4       R,VR&   T\         P                  ! 4       p	\        W,
          4      VR&   VR,          '       d   \        P                  RV 24       M\        P                  RV 24        \        P                  p
 \        TTRP                  VP                  R. 4      4      RP                  VP                  R. 4      4      RP                  VP                  R. 4      4      T \        P                  ! V4      \        P                  ! VP                  R. 4      4      T
VR,          '       d   RMRVP                  R
4      '       d"   RP                  VP                  R
. 4      4      MRR7       # VR,          P                  R-4       R.VR&   R/VR&   T\         P                  ! 4       p	\        W,
          4      VR&   VR,          '       d   \        P                  RV 24       M\        P                  RV 24        \        P                  p
 \        TTRP                  VP                  R. 4      4      RP                  VP                  R. 4      4      RP                  VP                  R. 4      4      T \        P                  ! V4      \        P                  ! VP                  R. 4      4      T
VR,          '       d   RMRVP                  R
4      '       d"   RP                  VP                  R
. 4      4      MRR7       # RVR,          RVR,          RVR,          R	\-        VR,          4      \-        VR,          4      ,           \-        VR,          4      ,           /VR&   . pV Fz  p\/        V4      pVR0,          '       d<   VP                  V4       VR,          P                  VP                  R1R24      4       KX  VR,          P                  R3VR,           24       K|  	  \1        W.4      p \3        V 3/ VB p \5        TTR,          TR,          '       d
   TR,          MRTR,          '       d
   TR,          MRTTP                  R74      R87      pT FC  p \7        TT4      pTR,          '       g%   TR,          P                  R9TR,           24       KC  KE  	  \9        \         4      pTP;                  T4       R.TR&   R=TR,          R	,           R>2TR&   \        P                  R?T  24       \         P                  ! 4       p	\        Y,
          4      TR&   TR,          '       d   \        P                  RT 24       M\        P                  RT 24        \        P                  p
 \        TTRP                  XP                  R. 4      4      RP                  TP                  R. 4      4      RP                  TP                  R. 4      4      T \        P                  ! T4      \        P                  ! TP                  R. 4      4      T
TR,          '       d   RMRTP                  R
4      '       d"   RP                  TP                  R
. 4      4      MRR7       T#   \         d    Rp
 ELLi ; i  \         d,   p\        P                  R\        T4       24        Rp?# Rp?ii ; i  \         d    Rp
 ELi ; i  \         d,   p\        P                  R\        T4       24        Rp?# Rp?ii ; i  \         d    Rp
 E	Li ; i  \         d,   p\        P                  R\        T4       24        Rp?# Rp?ii ; i  \         d    Rp
 ELi ; i  \         d,   p\        P                  R\        T4       24        Rp?# Rp?ii ; i  \         d    Rp
 ELi ; i  \         d,   p\        P                  R\        T4       24        Rp?# Rp?ii ; i  \         Ed   pTR
,          P                  R4T  R5\        T4       24       R6TR&   Tu Rp?\         P                  ! 4       p	\        Y,
          4      TR&   TR,          '       d   \        P                  RT 24       M\        P                  RT 24        \        P                  p
M  \         d    Rp
 Mi ; i \        TTRP                  TP                  R. 4      4      RP                  TP                  R. 4      4      RP                  TP                  R. 4      4      T \        P                  ! T4      \        P                  ! TP                  R. 4      4      T
TR,          '       d   RMRTP                  R
4      '       d"   RP                  TP                  R
. 4      4      MRR7       #   \         d,   p\        P                  R\        T4       24        Rp?# Rp?ii ; iRp?ii ; i  \         dD   pTR,          P                  R:TP                  R1R;4       R<\        T4       24        Rp?EK  Rp?ii ; i  \         Ed   pTR
,          P                  R@\        T4       24       RATR&   \        P                  R@\        T4       24       Tu Rp?\         P                  ! 4       p	\        Y,
          4      TR&   TR,          '       d   \        P                  RT 24       M\        P                  RT 24        \        P                  p
M  \         d    Rp
 Mi ; i \        TTRP                  TP                  R. 4      4      RP                  TP                  R. 4      4      RP                  TP                  R. 4      4      T \        P                  ! T4      \        P                  ! TP                  R. 4      4      T
TR,          '       d   RMRTP                  R
4      '       d"   RP                  TP                  R
. 4      4      MRR7       #   \         d,   p\        P                  R\        T4       24        Rp?# Rp?ii ; iRp?ii ; i  \         dV   pTR
,          P                  RB\        T4       24       RCTR&   \        P                  RD\        T4       24        Rp?ELRp?ii ; i  \         d    Rp
 EL`i ; i  \         d-   p\        P                  R\        T4       24        Rp?T# Rp?ii ; i  \         P                  ! 4       p	\        Y,
          4      TR&   TR,          '       d   \        P                  RT 24       M\        P                  RT 24        \        P                  p
M  \         d    Rp
 Mi ; i \        TTRP                  XP                  R. 4      4      RP                  TP                  R. 4      4      RP                  TP                  R. 4      4      T \        P                  ! T4      \        P                  ! TP                  R. 4      4      T
TR,          '       d   RMRTP                  R
4      '       d"   RP                  TP                  R
. 4      4      MRR7       i   \         d,   p\        P                  R\        T4       24        Rp?i Rp?ii ; i; i)FuT  
Función universal para envío de correos electrónicos utilizando Flask-Mail.

Args:
    template_path (str): Ruta del template HTML relativa a templates/
    asunto (str): Asunto del correo
    template_data (dict, optional): Datos para inyectar en el template
    mail_list_id (int, optional): ID de la lista de correos en Util_MailListHead
    destinatarios_adicionales (dict, optional): Destinatarios adicionales
        {'TO': ['email1@test.com'], 'CC': ['email2@test.com'], 'BCC': ['email3@test.com']}
    archivos_adjuntos (list, optional): Lista de archivos adjuntos
        [{'tipo': 'local', 'ruta': 'path/file.pdf', 'nombre': 'archivo.pdf'},
         {'tipo': 'url', 'ruta': 'https://...', 'nombre': 'archivo_web.pdf'}]
    configuracion_adicional (dict, optional): Configuraciones adicionales
    
Returns:
    dict: Resultado del envío
successFmensaje destinatariosTOCCBCCtotal_destinatarioserroreswarningsmail_list_idtemplate_usadoarchivos_enviadostiempo_ejecucionNztemplate_path es requeridou!   Parámetros de entrada inválidosz1Proceso completado exitosamente para MailListID: u    Proceso falló para MailListID: SYSTEM;ENVIADOFALLIDOz; )r   subjectrecipients_torecipients_ccrecipients_bcctemplate_usedtemplate_data
files_sentsent_bystatus	error_msgz Error al guardar log de correo: z[Sin Asunto]u6   No se encontró asunto en la BD, usando "[Sin Asunto]"u@   No se proporcionó asunto ni mail_list_id, usando "[Sin Asunto]"u*   Iniciando envío de correo para template: z(Obteniendo destinatarios de MailListID: zError al validar MailListID: u"   Error en validación de MailListIDexistezMailListID z no existe en la base de datosz
 no existeactivou    está inactivoz&Error al obtener destinatarios de BD: @z:Debe proporcionar mail_list_id o destinatarios_adicionalesz*No hay destinatarios para enviar el correou+   No se encontraron destinatarios TO válidosTz=Proceso completado con advertencias - no hay destinatarios TOvalidonombrearchivou   Archivo no válido: zError al renderizar template 'z': z Error en renderizado de templateMAIL_DEFAULT_SENDER)r!   
recipientsccbcchtmlsenderError al adjuntar archivo: zError al adjuntar archivo desconocidoz: zCorreo enviado exitosamente a z destinatariosz'Correo enviado exitosamente. Template: zError al enviar correo: u   Error en envío de correozError general: zError general en el procesoz*Error general en enviar_correo_universal: )r   r   r   )r   nowappendstrloggerinfoerrorr   email	Exceptionr   joingetjsondumpsr   r   configr
   warningr	   extendlenvalidar_archivo_adjuntopreparar_datos_templater   r   agregar_archivo_adjuntor   send)template_pathasuntor&   r   destinatarios_adicionalesarchivos_adjuntosconfiguracion_adicional	resultadoinicio_tiempo
fin_tiempor(   destinatarios_finalese	asunto_bdrE   
validaciondestinatarios_bdtipor?   archivos_validadosr0   resultado_validaciondatos_templatecuerpo_htmlmsgresultado_adjuntomails   &&&&&&&                    bC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\App\Utilities_module\MailManagement.pyenviar_correo_universalrc      s   < 	52$D"eR9NPQR2B-RD
I LLNMvF}i ''(DE#FIi d \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G
	F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@AcgC v|8F	"44n j)001ij+Fj)001st L \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G
	F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@Acgi ##%++-33"9"?"?R$=$C$C!@PQ "&r4UB ? <KKB<.QR 2,?Ji(()$++.KJW`LaKb,cd'K	)$ ^ \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G
	F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@Acg} h''*%,,{<.Hf-gh\N*EF))*%,,{<.-XY\N/JK $>l#K #I..)$/667G7MN)$/667G7MN)%0778H8OPj)003YZjktZuYv1wx %+449RSW9X9X!:4!@!@ 5SE\eCXY]C^6^1$7>>uE "A , %T**<(A(A)$++,hi'S	)$ ` \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G
	F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@Acg *%,,-Z['+	)$'f	)$ V \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G
	F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@Acgq '-'-(/!3'<T'B#CcJ_`dJeFf#fil  nC  DI  nJ  jK  $K	&
	/"  (G#:7#C #H--"))'2-.55gkk(I6VW*%,,/CDXYbDcCd-ef ) 1G	)-J>JK"	062G2M2M(.SW4I%4P4P)%0VZ zz"78C .@(?W(M%,Y77!*-447RSdenSoRp5qr 8 . $DIIcN $(Ii %CIoD^_tDuCv  wE  $FIi KKA-QR \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G
	F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@Acg  +  	G	$  	FLL;CF8DEE	F%  	G	$  	FLL;CF8DEE	F%  	G	$  	FLL;CF8DEE	F%  	G	$  	FLL;CF8DEE	F%  	G	$  	FLL;CF8DEE	F_  	i ''*HWZ[^_`[aZb(cd#EIi \ \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G 	G		F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@Acg  	FLL;CF8DEE	F_	. ! @j)003MgkkZbdqNrMssuvyz{v|u}1~@  	i ''*B3q6((KL#>Ii LL3CF8<= \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G 	G		F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@Acg  	FLL;CF8DEE	FW	  L)##oc!fX$>?<	)A#a&JKKL&  	G	$  	FLL;CF8DEE	F= \\^
(+J,F(G	$% YKKKL>Z[LL;L>JK	"((G 	G		F)!hh'<'@'@r'JK!hh'<'@'@r'JK"xx(=(A(A%(LM+"jj7::imm4G&LM$-i$8$8yiEN]]S\E]E]$))IMM)R$@Acg  	FLL;CF8DEE	Fs  'AP xCx$!(x$
AP AP AP 0
AP ;4AP y*Cy16(y1AP 8AP AP AP +AP AAP z*Cz>*(z>AP "AAP 'CAP ?	AP AP AP 4AP =AP /AP =AP AP AP {7(C|4(|#AP *};C}(}0C-AP ~ +5AG% !&AG% =AFAAG% 	AQ) CAQ= &(AQ= x! x!$y/!yyy.-y.1z'<!z""z'*z;:z;>{4	!{//{47||}!|<<}}}~#!~		~AF-AF
AFAP @9AA
A
AAAAAACAED*(AEEAF	E!AFFAF	FAFFAP FAG"F7AGGAG% GAG"G"AG% G%APG1AAO>H<APH=AP J+AJ<J<AKKAKKCAON(AOOAO;O!AO6O6AO;O>APPAP PAQ&PA
AQ!QAR7 Q!AQ&Q&AR7 Q)AQ:Q9AQ:Q=AR4R!AR/R/AR4R7A*AY5T"AT3T2AY5T3AUU AY5UAUUAY5UCAX<X(AX<X;AY5X<AY2Y!AY-Y(AY5Y-AY2Y2AY5c                   \        V \        4      '       g	   RRRRRR/# V P                  R4      pV P                  RR4      pV'       g	   RRRR	RV/#  VR8X  d   \        P                  P                  V4      '       dY   \        P                  P                  V4      '       d4   \        P                  ! V\        P                  4      '       d	   RR
RRRR/# RRRRV 2RR/# VR8X  dV   ^ RI	pVP                  P                  V4      pVP                  R9   d   VP                  '       d	   RR
RRRR/# RRRRV 2RR/# RRRRV R2RV/#   \         d   pRRRR\        T4       2RT/u Rp?# Rp?ii ; i)u  
Valida si un archivo adjunto es válido (local o URL).

Args:
    archivo (dict): Diccionario con información del archivo
                   {'tipo': 'local', 'ruta': '/path/to/file', 'nombre': 'archivo.pdf'}
                   {'tipo': 'url', 'ruta': 'https://...', 'nombre': 'archivo.pdf'}

Returns:
    dict: Resultado de la validación
          {'valido': True/False, 'mensaje': 'descripción', 'tipo': 'local/url'}
r.   Fr   zArchivo debe ser un diccionariorZ   NrutalocalzRuta del archivo es requeridaTu   Archivo local válidoz,Archivo local no encontrado o no accesible: urlu   URL válidau   URL inválida: u   Tipo de archivo no válido: z. Use "local" o "url"zError al validar archivo: )httphttps)
isinstancedictrB   ospathexistsisfileaccessR_OKurllib.parseparseurlparseschemenetlocr@   r;   )r0   re   rZ   urllib
parsed_urlrV   s   &     rb   rI   rI      s    gt$$%,MvW[\\;;vD;;vw'D%,KVUYZZa7?ww~~d##t(<(<4QSQXQXAYAY $	3JFT[\\ %6bcgbh4ikqsz{{U]..t4J  $55*:K:K:K $	=&%PP %odV4LfV[\\ eY2NtfTi0jlrtxyy a%.HQ,QSY[_``asO   +E
 ?$E
 $*E
 E
 
E
 "AE
 +E
 3
E
 >E
 
E3E.(E3.E3c                    VP                  RR4      pVP                  R4      pVP                  RR4      pVP                  RR4      pVR8X  dG   \        VR4      ;_uu_ 4       pV P                  WEVP                  4       4       R	R	R	4       R
RRRV 2/# VR8X  d]   ^ R	Ip VP
                  P                  V4      ;_uu_ 4       pVP                  4       p	V P                  WEV	4       R	R	R	4       R
RRRV 2/# R
RRRV 2/#   + '       g   i     L; i  + '       g   i     L5; i  \         d   p
R
RRR\        T
4       2/u R	p
?
# R	p
?
ii ; i  \         d   p
R
RRR\        T
4       2/u R	p
?
# R	p
?
ii ; i)u   
Agrega un archivo adjunto al mensaje de correo.

Args:
    msg (Message): Mensaje de Flask-Mail
    archivo (dict): Información del archivo
    
Returns:
    dict: Resultado de la operación
rZ   rf   re   r/   archivo_adjuntomimetypezapplication/octet-streamrbNr   Tr   zArchivo local adjuntado: rg   zArchivo URL adjuntado: Fz&Error al descargar archivo desde URL: zTipo de archivo no soportado: r7   )	rB   openattachreadurllib.requestrequesturlopenr@   r;   )r_   r0   rZ   re   r/   r{   fprw   responsedatarV   s   &&         rb   rK   rK   )  sy   U{{67+{{6"X'89;;z+EF7?dD!!R

6RWWY7 "tY2KF80TUUU]!h^^++D11X#==?DJJv6 2 "46MfX4VWW
 ui3QRVQW1XYY! "! 21  h!5)7]^abc^d]e5fggh  U5)/J3q6(-STTUs   A"E $!DE E "#D( #D(D( 9E D	E D%	 D( (E3E
EE 
EE E9E4.E94E9c                t   R\         P                  ! 4       P                  R\         P                  ! 4       P                  R4      RRRRRVP	                  R	R
4       RVP	                  RR4       2RVP	                  R	R
4       RVP	                  RR4       R2RRRRRR/	pV '       d   VP                  V 4       V# )u   
Prepara los datos que se enviarán al template, incluyendo variables globales.

Args:
    template_data (dict): Datos específicos del template
    config (Config): Configuración de Flask
    
Returns:
    dict: Datos completos para el template
u   año_actualfecha_actualz%d de %B, %YempresaIGSAempresa_completaz"Integradora de Servicios Avanzadosurl_baseSCHEMErh   z://Host	localhostlogo_empresaz/static/img/logo.pngsoporte_emailzsoporte@igsa.comventas_emailzventas@igsa.comtelefono_principalz+52 (999) 123-4567)r   r9   yearstrftimerB   update)r&   rE   datos_completoss   && rb   rJ   rJ   S  s     	x||~**//?6@vzz(F34C

6;8W7XY6::h78FJJv{<[;\\pq+)2
O }-    c                    \        V 4      p\        V 4      pRV RVP                  RR4      RVP                  RR4      RVP                  R4      RVP                  R4      RVP                  R^ 4      RR	\        VP                  R	. 4      4      R
\        VP                  R
. 4      4      R\        VP                  R. 4      4      /RRRR/	pV#   \         d   pRRRR\        T4       2/u Rp?# Rp?ii ; i)u   
Obtiene información resumida sobre el envío de correo.

Args:
    mail_list_id (int): ID de la lista de correos
    
Returns:
    dict: Información del envío
r   r+   Fr,   r!   	module_idr   destinatarios_por_tipor   r   r   r   Tr   u#   Información obtenida correctamenteu   Error al obtener información: N)r
   r	   rB   rH   r@   r;   )r   rX   r   r=   rV   s   &    rb   obtener_info_envior   s  s	   
-l;
2<@ LjnnXu5jnnXu5z~~i04!=#4#45JA#N$c-++D"56c-++D"56s=,,UB78'
 t<
   
u8QA
 	

s   C
C C4C/)C4/C4c                     \         P                  pT;'       g    / p\        W#4      p\        V 4      p\	        V3/ VB pRVRVRVRVRRRR/pV#   \
         d   pRR	RR
\        T4       2/u Rp?# Rp?ii ; i)a  
Genera una vista previa del correo sin enviarlo.

Args:
    mail_list_id (int): ID de la lista de correos
    template_path (str): Ruta del template HTML
    template_data (dict, optional): Datos para el template
    
Returns:
    dict: Preview del correo
html_content
info_envior]   rM   r   Tr   zPreview generado correctamenteFzError al generar preview: N)r   rE   rJ   r   r   r@   r;   )	r   rM   r&   rE   r]   r   r^   previewrV   s	   &&&      rb   generar_preview_correor     s    
##%++ 1G (5
 &mF~F K*n]t7
  
u3CF8<
 	

s"   A 4A A7A2,A72A7)NNNNNN)N)rl   rC   loggingflask_loginr   r   flaskr   r   
flask_mailr   r   )Consultas_SQL.Utilities.MailManagementSQLr	   r
   r   r   basicConfigINFO	getLogger__name__r<   rc   rI   rK   rJ   r   r    r   rb   <module>r      sr    
   $  . $ \  \   ',, '			8	$cL,a^'UT@&
R)
r   