a
    0ivv                  	   @   s   d Z ddlZddlZddlmZ ejejejeje ddl	m
Z
 ddlmZ ddlZddlZddlZddlZddlmZ G dd deZG d	d
 d
ZdS )z
Recuperar_formulariosYpdf.py

Script de prueba para generar PDFs de formularios desde el backend
sin necesidad de pasar por la API Flask.
    N)datetime)get_connection)FPDF)Pathc                       sJ   e Zd ZdZ fddZdd Zdd Zdd	 ZdddZdd Z	  Z
S )PDFzE
    Clase personalizada para PDF con identidad corporativa IGSA
    c                    s   t    d| _d S )N )super__init__form_idself	__class__ Q/var/www/html/src/App/Operaciones_Module/Ingenieria/Cotiz/FormularioPDFService.pyr	      s    
zPDF.__init__c              	   C   sN   |  ddd | ddd | ddd | dd	d
dddd | d dS )u3   Encabezado de cada página con colores corporativosArialB   [            r      u   Información de Formulario   C   Nset_fontset_fill_colorset_text_colorcelllnr   r   r   r   header!   s
    z
PDF.headerc                 C   sJ   |  d | ddd | ddd | ddd|   d	ddd
 dS )u   Pie de páginair   I   f   r   
   u   Página z/{nb}r   N)Zset_yr   r   r    Zpage_nor   r   r   r   footer)   s    
z
PDF.footerc              	   C   sN   |  ddd | ddd | ddd | dd	|dd
dd
 | d dS )u4   Crea un título de sección con colores corporativosr   r      .   \      r   r   r&   r   L   Nr   )r   Ztitulor   r   r   seccion_titulo0   s
    zPDF.seccion_titulo         c              	   C   st   |  ddd | j|  | ddd | dd|dd	d
d |  ddd | ddd | d	dt|ddd
 dS )z+Crea una fila de datos con etiqueta y valorr   r   r&   r)   r*   r+   <   r   r   r,   r   3   N)r   r   r   r    str)r   Zetiquetavalorbg_colorr   r   r   
fila_datos8   s    
zPDF.fila_datosc                 C   s   d}| j | j | j | }|  }| | j| | ddd | ddd | dd	d
 | |dt	|d ddd | | j| | | ddd | ddd | ddd | |dt	|ddd dS )zv
        Crea una fila con pregunta y respuesta en formato simplificado
        con colores corporativos IGSA
        F   r   r   r&   r0   r1   r2   r)   r*   r+      :r   r,   Tr   r   r4   N)
wZl_marginZr_marginZget_yZset_xyr   r   r   
multi_cellr5   )r   pregunta	respuestaZancho_preguntaZancho_respuestaZ	y_inicialr   r   r   fila_pregunta_respuestaC   s    zPDF.fila_pregunta_respuesta)r/   )__name__
__module____qualname____doc__r	   r"   r'   r.   r8   r@   __classcell__r   r   r   r   r      s   
r   c                   @   s   e Zd ZdZeeedddZedddZedd	 Z	ededddZ
eeedddZedeeeedddZeeeedddZededddZd
S )FormularioPDFServicezJ
    Servicio para generar PDFs de formularios desde la base de datos
    )r
   returnc                 C   s  t d|   d}zt t}| H}||| f | }|srt d|   W d   W d   W dS t dt| d |d }|d |d |d	 |d
 |d |d |d g d}t dt| d t|dD ]Z\}}|d |d |d |d d}	|d |	 |d dkrt d| dt| d qt dt|d   |W  d   W  d   W S 1 sz0    Y  W d   n1 s0    Y  W nF ty }
 z,t d|
  ddl	}|
  W Y d}
~
dS d}
~
0 0 dS )a  
        Obtiene los datos del formulario desde la base de datos
        
        Args:
            form_id (str): ID del formulario (ej: '1002-1-FormGral')
            
        Returns:
            dict: Diccionario con los datos del formulario o None si no existe
        u!   🔍 Buscando datos para FormID: u  
        SELECT 
            fh.FormID,
            fh.CreatedAt,
            COALESCE(NULLIF(RTRIM(LTRIM(fh.CreatedBy)), ''), 'Sin información') AS CreatedBy,
            COALESCE(NULLIF(RTRIM(LTRIM(qt.FrontES)), ''), 'Sin información') AS FrontES,
            COALESCE(NULLIF(RTRIM(LTRIM(fd.Question)), ''), 'Sin información') AS Question,
            COALESCE(NULLIF(RTRIM(LTRIM(fd.TypeQuestion)), ''), 'Sin información') AS TypeQuestion,
            COALESCE(NULLIF(RTRIM(LTRIM(fd.Answer)), ''), 'Sin información') AS Answer,
            COALESCE(NULLIF(RTRIM(LTRIM(p.Email)), ''), 'Sin información') AS Email,
            COALESCE(NULLIF(RTRIM(LTRIM(p.ContactPhone)), ''), 'Sin información') AS ContactPhone,
            COALESCE(NULLIF(RTRIM(LTRIM(p.FirstName)), ''), 'Sin información') AS FirstName,
            fd.FormLineID
        FROM 
            Q_SpQ_FormsHead fh
        INNER JOIN Q_QuotationType qt ON fh.QuotationTypeID = qt.QuotationTypeID
        LEFT JOIN Q_SpQ_FormsDetail fd ON fh.FormID = fd.FormID
        LEFT JOIN Profiles p ON fh.UserID = p.UserID
        WHERE 
            fh.FormID = ?
        ORDER BY 
            fd.FormLineID
        u)   ❌ No se encontraron datos para FormID: N   ✅ Se encontraron z registros (preguntas)r   r   r-   r   r:   r$   	   )FormID	CreatedAt	CreatedByFrontESEmailContactPhone	FirstName	preguntasu   📝 Procesando z preguntas:r&            )Z
FormLineIDQuestionZTypeQuestionAnswerrQ   u      ↳ Procesadas /z preguntas...u#   ✅ Total de preguntas capturadas: u)   ❌ Error al consultar la base de datos: )printr   cursorexecutefetchalllen	enumerateappend	Exception	traceback	print_exc)r
   queryconnrY   rowsZprimera_filadatosidxrowr>   er`   r   r   r   obtener_datos_formularioa   sL    
Xz-FormularioPDFService.obtener_datos_formularioreportesc                 C   sZ   t jt jt}t j|| }t j|sHt | td|  ntd|  |S )uR   
        Crea el directorio donde se guardarán los reportes si no existe
           📁 Directorio creado: u"   📁 Usando directorio existente: )	ospathdirnameabspath__file__joinexistsmakedirsrX   )Zdirectorio_baseZ
script_dirZruta_reportesr   r   r   crear_directorio_reportes   s    
z.FormularioPDFService.crear_directorio_reportesc              
   C   s   zVt  }|dkrt|  n.|dkr:td|  d ntd|  d td W n@ ty } z(td|  td|   W Y d	}~n
d	}~0 0 d	S )
zV
        Abre el archivo PDF generado con el visor predeterminado del sistema
        WindowsDarwinzopen ""z
xdg-open "u%   📄 Archivo abierto automáticamenteu6   ⚠️  No se pudo abrir el archivo automáticamente: z%   Puedes abrirlo manualmente desde: N)platformsystemrl   Z	startfilerX   r_   )ruta_archivoZsistemarh   r   r   r   abrir_archivo   s    z"FormularioPDFService.abrir_archivoNT)r
   c              
   C   s*  t d t d t d t d|   t   t| }|sFt d dS td}|du rt d}d| d	d
 d
| d}tj	
||}t d|  t d|  t   zt d t }| |_|  |  |ddd |ddd |ddddd |d t d |d |d|d d |dt|d d |d|d  d |d!|d" d |d t d# |d$ |d%|d& d |d'|d( d |d)|d* d |d t d+t|d,  d- |d. |d/ t|d, d0D ]J\}}	|d dkr8t d1| d2t|d,  d3 ||	d4 |	d5  qt d1t|d,  d2t|d,  d6 t d7 |d |dd8d9 |ddd t d:}
|ddd;|
 dd0d t   t d< || tj	|rtj	|d= }t d> t d?|d@dA nt dB W dS t   t d t dC t d t dD|  t dE|  t dF|  t d |rt   t| |W S  ty$ } ztt   t d t dG t d t dHt|j   t dI|  t   t dJ ddl!}|"  t d W Y d}~dS d}~0 0 dS )Ku  
        Genera un PDF del formulario especificado
        
        Args:
            form_id (str): ID del formulario (ej: '1001-1')
            nombre_archivo (str, optional): Nombre del archivo PDF
            abrir_al_finalizar (bool): Si es True, abre el PDF automáticamente
            
        Returns:
            str: Ruta completa del archivo generado o None si hay error
        P================================================================================u)   🚀 INICIANDO GENERACIÓN DE REPORTE PDF   📋 FormID solicitado: 3   ❌ No se pudieron obtener los datos del formularioNrj   %Y%m%d_%H%M%Sformulario_-_.pdfu   💾 Nombre del archivo: u   📂 Ubicación completa:    📝 Generando documento PDF...r   r   r&   r%   r   rS   u`   Bienvenido. Módulo para Información del formulario, diseñado para el área comercial de IGSA.r   r$   /      ↳ Agregando información del formulario...Datos de la OportunidadForm ID:rJ   r/      Fecha de Creación:rK   Creado Por:rL   Tipo de Formulario:rM   ,      ↳ Agregando información del usuario...   Información del UsuarioNombre:rP   Email:rN   
   Teléfono:rO         ↳ Procesando rQ    preguntas y respuestas...Detalles del Formularior-   r            • Procesadas rW   
 preguntasrU   rV       preguntas ✓/      ↳ Agregando información de generación...r#   rI   %d/%m/%Y %H:%M:%SReporte generado el    💾 Guardando archivo PDF...   u!   ✅ Archivo guardado exitosamenteu   📏 Tamaño del archivo: .2fz KB(   ❌ ERROR: El archivo no se pudo guardar#   ✨ PROCESO COMPLETADO EXITOSAMENTEu   📄 Archivo generado: u   📂 Ubicación: u   🔗 Ruta completa: u   ❌ ERROR INESPERADOzTipo de error: z
Detalles: zStack trace completo:)#rX   rF   ri   rt   r   nowstrftimereplacerl   rm   rq   r   r
   alias_nb_pagesadd_pager   r   r=   r!   r.   r8   r5   r\   r]   r@   r    outputrr   getsizer{   r_   typerA   r`   ra   )r
   nombre_archivoZabrir_al_finalizarre   directorio_reportes	timestampruta_completapdfrf   r>   	fecha_gen
   tamaño_kbrh   r`   r   r   r   generar_pdf   s    








&


z FormularioPDFService.generar_pdf)docs_idrG   c           
   
   C   sd  t d|   d}zt }| }||| f | }|srt d|   g W  d   W  d   W S g }|D ]2}|d |d |d |d |d	 d
}|| qzt dt| d |W  d   W  d   W S 1 s0    Y  W d   n1 s
0    Y  W nH ty^ } z.t d|  ddl}	|		  g W  Y d}~S d}~0 0 dS )u  
        Obtiene los archivos adjuntos asociados al DocsID desde Q_SpQ_DocsDetail
        
        Args:
            docs_id (int): ID del documento
            
        Returns:
            list: Lista de diccionarios con información de los archivos
        u-   🔍 Buscando archivos adjuntos para DocsID: a#  
        SELECT 
            DocLineID,
            DocsID,
            DocLine,
            RTRIM(LTRIM(Title)) AS Title,
            RTRIM(LTRIM(Ruta)) AS Ruta
        FROM 
            Q_SpQ_DocsDetail
        WHERE 
            DocsID = ?
        ORDER BY 
            DocLineID
        u<      ℹ️  No se encontraron archivos adjuntos para DocsID: Nr   r   r-   r   rR   )Z	DocLineIDDocsIDZDocLineTitleRutarH    archivo(s) adjunto(s)u*   ❌ Error al consultar archivos adjuntos: )
rX   r   rY   rZ   r[   r^   r\   r_   r`   ra   )
r   rb   rc   rY   rd   archivosrg   archivorh   r`   r   r   r   obtener_archivos_adjuntosk  s4    
"Vz.FormularioPDFService.obtener_archivos_adjuntos)ruta_origendirectorio_destinor   rG   c              
   C   s  ddl }ddlm}m} zf| dp.| d}|r|du rX|| }|tj|j}t|| }t	d |j
| ddd	}	|	  t|d
0}
|	jddD ]}|r|
| qW d   n1 s0    Y  | r| jd }t	d| d|dd t|W S t	d W dS nft| }| s>t	d|   W dS |du rN|j}t|| }t|| t	d|  t|W S W n~ |jjy } zt	d|  W Y d}~dS d}~0  ty } z,t	d|  ddl}|  W Y d}~dS d}~0 0 dS )u  
        Descarga un archivo desde una URL o copia desde una ruta local
        
        Args:
            ruta_origen (str): URL o ruta local del archivo
            directorio_destino (str): Directorio donde se guardará el archivo
            nombre_archivo (str, optional): Nombre personalizado para el archivo
            
        Returns:
            str: Ruta completa del archivo descargado o None si hay error
        r   N)urlparseunquotezhttp://zhttps://u       🌐 Descargando desde URL...   T)timeoutstreamwbi    )
chunk_sizer   u      ✅ Descargado: z (r    KB)u-      ❌ El archivo no se guardó correctamenteu"      ⚠️  Archivo no encontrado: u      ✅ Copiado: u"      ❌ Error de red al descargar: u"      ❌ Error al procesar archivo: )requestsurllib.parser   r   
startswithrl   rm   basenamer   rX   getraise_for_statusopeniter_contentwriterr   statst_sizer5   nameshutilcopy2
exceptionsRequestExceptionr_   r`   ra   )r   r   r   r   r   r   Zes_url
parsed_urlZdestinoresponsefchunkr   origenrh   r`   r   r   r   descargar_archivo  sP    *



z&FormularioPDFService.descargar_archivo)r   ruta_ziprG   c              
   C   s   zvt |dt j<}| D ]&}|rt| r||t|j qW d   n1 sT0    Y  tdt|j  W dS  ty } ztd|  W Y d}~dS d}~0 0 dS )uP  
        Crea un archivo ZIP con todos los archivos descargados
        
        Args:
            archivos (list): Lista de rutas de archivos a incluir en el ZIP
            ruta_zip (str): Ruta donde se guardará el archivo ZIP
            
        Returns:
            bool: True si se creó exitosamente, False si hay error
        r<   N   📦 ZIP creado: Tu   ❌ Error al crear ZIP: F)	zipfileZipFileZIP_DEFLATEDr   rr   r   r   rX   r_   )r   r   zipfr   rh   r   r   r   crear_zip_con_archivos  s    2z+FormularioPDFService.crear_zip_con_archivosc              
   C   s  t d t d t d t d|   t d|r2dnd  t d|rHdnd  t   t| }|srt d d	S zt| d
d }W n   t d d	}Y n0 td}d| d
d }tj	||}tj
|st| t d|  |d	u r"t d}	d| d
d d|	 d}tj	||}
t d|  t   zt d t }| |_|  |  |ddd |ddd |ddddd |d t d |d |d|d  d! |d"t|d# d! |d$|d% d! |d&|d' d! |d t d( |d) |d*|d+ d! |d,|d- d! |d.|d/ d! |d t d0t|d1  d2 |d3 |d4 t|d1 d5D ]J\}}|d dkrt d6| d7t|d1  d8 ||d9 |d:  qt d6t|d1  d7t|d1  d; t d< |d |dd=d> |ddd t d?}|ddd@| dd5d t   t dA ||
 dd	l}| dB tj
|
st dC W d	S tj!|
dD }t dE|dFdG W nH t"y } z.t   t dH| dd	l#}|$  W Y d	}~d	S d	}~0 0 |
g}|r|rt   t d t dI t d t%|}|rt dJt| dK t   t|d5D ]T\}}t dL| d7t| dM|dN   tj&|dO ||dN dP}|rx|'| qxt   t dQt|d5  dR nt dS d	}|rt|d5krt   t d t dT t d dU| d
d dt d dV}tj	||}t(||rtj!|dD }t dW|dFdG nd	}t   t d t dX t d t dY|  t dZ|  t d[t|d5   |r t d\tj)|  t d |
|d5d	 ||d]S )^a  
        Genera un PDF del formulario y descarga archivos adjuntos
        
        Args:
            form_id (str): ID del formulario (ej: '1002-1-FormGral')
            nombre_archivo (str, optional): Nombre del archivo PDF
            incluir_adjuntos (bool): Si es True, descarga archivos adjuntos
            crear_zip (bool): Si es True, crea un ZIP con PDF y adjuntos
            
        Returns:
            dict: Diccionario con rutas de archivos generados o None si hay error
        r|   u6   🚀 INICIANDO GENERACIÓN DE REPORTE PDF CON ADJUNTOSr}   u   📎 Incluir adjuntos: u   SíNou   📦 Crear ZIP: r~   Nr   r   u,   ⚠️  No se pudo extraer DocsID del FormIDrj   r   r   rk   r   r   u   💾 Generando PDF: r   r   r   r&   r%   rS   u_   Bienvenido. Módulo para Información de formulario, diseñado para el área comercial de IGSA.r   r$   r   r   r   rJ   r/   r   rK   r   rL   r   rM   r   r   r   rP   r   rN   r   rO   r   rQ   r   r   r-   r   r   rW   r   rU   rV   r   r   r#   rI   r   r   r   g?r   r   u   ✅ PDF guardado exitosamente (r   r   u   ❌ ERROR al generar PDF:u"   📎 DESCARGANDO ARCHIVOS ADJUNTOSu   📥 Descargando z archivo(s)...[z] r   r   )r   r   r   u   ✅ Descargados r   u8      ℹ️  No hay archivos adjuntos para este formulariou   📦 CREANDO ARCHIVO ZIPZpaquete_z.zipu   ✅ ZIP creado exitosamente (r   u   📄 PDF generado: u   📁 Ubicación: u   📎 Archivos adjuntos: r   )r   adjuntoszip
directorio)*rX   rF   ri   intsplitrt   r   rl   rm   rq   rr   rs   r   r   r   r   r
   r   r   r   r   r=   r!   r.   r8   r5   r\   r]   r@   r    r   timesleepr   r_   r`   ra   r   r   r^   r   r   )r
   r   incluir_adjuntos	crear_zipre   r   r   Znombre_carpetaZdirectorio_formularior   ruta_pdfr   rf   r>   r   r   r   rh   r`   Zarchivos_descargadosarchivos_adjuntosr   Zruta_descargadar   Z
nombre_zipt   tamaño_zip_kbr   r   r   generar_pdf_con_adjuntos  s   











&




"$
z-FormularioPDFService.generar_pdf_con_adjuntos)rj   )NT)N)NTT)rA   rB   rC   rD   staticmethodr5   dictri   rt   r{   r   r   listr   r   boolr   r   r   r   r   r   rF   \   s$   X
 9TrF   )rD   sysrl   r   rm   r^   rn   ro   rp   Consultas_SQL.conexionr   Zfpdfr   rx   r   r   r   pathlibr   r   rF   r   r   r   r   <module>   s   $C