
    tz0i                         S SK JrJrJrJrJrJrJr  S SKJ	r	  S SK
r
S SKrS SKJr  S SKJrJr  S SKrS SKrS SKJr  S SKJrJrJrJrJrJrJrJr  S SKJr  S S	KJr  S SKr\
R@                  " S
5      r!S r"g)    )current_apprender_templaterequestsessionjsonifyredirecturl_for)wrapsNdatetime)DictList)
CRMManager)buscar_cotizacion_completaactualizar_lineas_cotizacionactualizar_calculo_financieroactualizar_tiempo_y_condicionesfinalizar_cotizacion_y_enviarget_Quote_JSON_BussinessCentraljson_serializerget_TermsType_JSON)RecepcionCotizSQLenviar_correo_universalrecepcion_cotizacionc                   ^ ^ Sn  T R                  U S3S/S9S[        4S j5       n T R                  U S3S/S9S 5       n T R                  U S	3S/S9S
 5       n T R                  U S3S/S9S[        4S j5       n T R                  U S3S/S9S 5       n T R                  U S3SS/S9S 5       n T R                  U S3S/S9S 5       n	T R                  SS/S9S 5       n
T R                  SS/S9U4S j5       nT R                  U S3S/S9U 4S j5       nT R                  U S3S/S9S[        4U 4S jj5       nT R                  U S3S/S9S[        4S j5       nS[        S [        S![        S"[        4U 4S# jjmg )$Nz/Ventas/Cotiz/Recepcionz/costing/<int:costing_num>GET)methodscosting_numc                      [         R                  " U 5      nU(       a  [        UR                  5       5      $ [        SSU  S305      S4$ ! [         a  n[        SS05      S4s SnA$ SnAff = f)u   
Controlador para obtener datos unificados de la cotización (Costeo y CRM).
Ruta final: /api/reception/costing/<int:costing_num>
erroru   Cotización con número z no encontrada  (   Ocurrió un error interno en el servidor  N)r   get_unified_data_by_costing_numr   to_dict	Exception)r   data_dtoes      eC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\App\Ventas_Module\Cotiz\RecepcionCotiz.py get_reception_costing_controllerNregistrar_rutas_recepcion_cotizacion.<locals>.get_reception_costing_controller,   s{    	W(HHUHx//122 +CK=P^)_`acfff 	WG%OPQSVVV	Ws"   5A A 
A.A)#A.)A.z/taxesc                       [         R                  " 5       n [        U 5      $ ! [         a  n[        SS05      S4s SnA$ SnAff = f)zR
Controlador para obtener la lista de impuestos.
Ruta final: /api/reception/taxes
r!   r#   r$   N)r   	get_taxesr   r'   )taxesr)   s     r*   get_taxes_controllerBregistrar_rutas_recepcion_cotizacion.<locals>.get_taxes_controllerB   sI    	W%//1E5>! 	WG%OPQSVVV	Ws   " 
AA A Az/currenciesc                       [         R                  " 5       n [        U 5      $ ! [         a'  n[	        SU 35        [        SS05      S4s SnA$ SnAff = f)zU
Controlador para obtener la lista de monedas.
Ruta final: /api/reception/currencies
z4Error en el controlador quote_reception/currencies: r!   r#   r$   N)r   get_currenciesr   r'   print)
currenciesr)   s     r*   get_currencies_controllerGregistrar_rutas_recepcion_cotizacion.<locals>.get_currencies_controllerQ   sZ    	W*99;J:&& 	WHLMG%OPQSVVV	Ws   " 
AAAAz"/costing-details/<int:costing_num>c                      [         R                  " U 5      n[        U5      $ ! [         a'  n[	        SU 35        [        SS05      S4s SnA$ SnAff = f)un   
Controlador para obtener las líneas de costeo.
Ruta final: /api/reception/costing-details/<int:costing_num>
z9Error en el controlador quote_reception/costing-details: r!   r#   r$   N)r   get_costing_detailsr   r'   r4   )r   detailsr)   s      r*   get_costing_details_controllerLregistrar_rutas_recepcion_cotizacion.<locals>.get_costing_details_controllera   s\    	W';;KHG7## 	WMaSQRG%OPQSVVV	Ws    # 
AA	AAz/create-quotationPOSTc                  $    [         R                  " 5       n [        R                  " U 5      nUR	                  S5      (       a  [        U5      S4$ [        U5      S4$ ! [         a(  n[        SU 35        [        SSS.5      S4s S	nA$ S	nAff = f)
u[   
Controlador para crear una nueva cotización.
Ruta final: /api/reception/create-quotation
success     z*Error en el controlador create-quotation: Fr#   r?   r!   r$   N)r   get_jsonr   create_quotationgetr   r'   r4   )dataresultr)   s      r*   create_quotation_controllerIregistrar_rutas_recepcion_cotizacion.<locals>.create_quotation_controllerq   s    	i##%D&77=Fzz)$$v++v++ 	i>qcBCu7abcehhh	is$   AA A 
B'B
B
Bz/preview-quotationOPTIONSc                  6   [         R                  S:X  ae  [        SS05      n U R                  R	                  SS5        U R                  R	                  SS5        U R                  R	                  SS	5        U S
4$  [         R
                  " 5       nU(       a  [        U5      S::  Ga  [        S5        SnU(       a8  UR                  S5      =(       d    [         R                  R                  S5      nO[         R                  R                  S5      nU(       Ga  SSK	nSSK
nSSKJn  UR                  R                  UR                  SSSS5      nUR                  R                  USU S35      n[        SU 35        UR                  R!                  U5      (       at  [#        USSS9 nUR$                  " U5      nSSS5        [        S5        [        S['        UR)                  5       5       35         UR+                  U5        [        S5        O'[        S U 35        S!U S"U S#3n
U
S$S%S&04$ S'n
U
S$S%S&04$ U(       d	  S(n
U
S$S%S&04$ UR                  S5      =(       d    [         R                  R                  S5      n[        S)5        [        S*U 35        [        S+['        UR)                  5       5       35        [.        R0                  " U5      nU(       a  [        S,[        U5       S-35        US
S%S&04$ S.n
U
S/S%S&04$ ! , (       d  f       GNN= f! [,         a  n	[        SU	 35         Sn	A	NSn	A	ff = f! [,         aS  n	[        S0U	 35        SSKnUR5                  5         S1[7        U	5       S2UR9                  5        S33n
U
S/S%S&04s Sn	A	$ Sn	A	ff = f)4ux   
Controlador para generar vista previa de la cotización antes de crearla.
Ruta final: /api/reception/preview-quotation
rJ   statusokzAccess-Control-Allow-Origin*zAccess-Control-Allow-HeaderszContent-Type,X-Auth-TokenzAccess-Control-Allow-Methodsr=         uO   ⚠️ Datos incompletos recibidos, intentando cargar desde archivo temporal...NtokenzX-Auth-Tokenr   )r   staticpdfVentasCotiz
temp_data_.jsonu   🔍 Buscando archivo: rutf-8encodingu)   ✅ Datos cargados desde archivo temporalu   📦 Datos cargados: u"   🗑️ Archivo temporal eliminadou-   ⚠️ No se pudo eliminar archivo temporal: u$   ❌ Archivo temporal no encontrado: u   
                        <!DOCTYPE html>
                        <html>
                        <body>
                            <h1>❌ Error: No se encontraron datos de cotización</h1>
                            <p>Token: z5</p>
                            <p>Archivo buscado: z]</p>
                        </body>
                        </html>
                        rA   zContent-Typeztext/html; charset=utf-8u   
                    <!DOCTYPE html>
                    <html>
                    <body>
                        <h1>❌ Error: No se recibió token</h1>
                    </body>
                    </html>
                    u   
                <!DOCTYPE html>
                <html>
                <body>
                    <h1>❌ Error: No se pudieron cargar los datos</h1>
                </body>
                </html>
                u,   📋 Generando vista previa para cotizaciónu   🎫 Token recibido: u   📦 Datos recibidos: u   ✅ HTML generado: z caracteresu  
                <!DOCTYPE html>
                <html>
                <body>
                    <h1>❌ No se pudo generar la vista previa</h1>
                    <p>El servicio no retornó contenido HTML</p>
                </body>
                </html>
                r$   u    ❌ Error en preview-quotation: uQ  
            <!DOCTYPE html>
            <html>
            <head>
                <title>Error</title>
                <style>
                    body {
                        font-family: Arial, sans-serif;
                        padding: 40px;
                        background-color: #f5f5f5;
                    }
                    .error {
                        background-color: #fee;
                        border: 2px solid #f00;
                        padding: 20px;
                        border-radius: 8px;
                        max-width: 800px;
                        margin: 0 auto;
                    }
                    pre {
                        background-color: #333;
                        color: #fff;
                        padding: 15px;
                        overflow-x: auto;
                        border-radius: 4px;
                    }
                </style>
            </head>
            <body>
                <div class="error">
                    <h1>❌ Error al generar vista previa</h1>
                    <p><strong>Mensaje:</strong> z</p>
                    <pre>zR</pre>
                </div>
            </body>
            </html>
            )r   methodr   headersaddrC   lenr4   rE   osjsonflaskr   pathjoin	root_pathexistsopenloadlistkeysremover'   r   generate_quotation_preview	traceback	print_excstr
format_exc)responserF   rQ   r`   ra   r   
output_dirtemp_data_filefr)   
error_htmlpreview_htmlrm   s                r*   preview_quotation_controllerJregistrar_rutas_recepcion_cotizacion.<locals>.preview_quotation_controller   s    >>Y&$/0H  !>D  !?A\]  !?HS= O	Q##%D 3t9>gh HHW-T1D1D^1TE#OO//?E1!#k.C.CXuV^`g!hJ%'WW\\*
5'QV>W%XN3N3CDEww~~n55!.#HA#'99Q<D I IK 5d499;6G5HIJWIIn5!$FH  D^DTUV*'
 (-g .11?0@ A	&
  *3A[0\\\"J &s^=W,XXX 
 "39S(TTT HHW%L)<)<^)LE@B)%12*4		+<*=>? -GGML+C,=+>kJK#S>;U*VVV
 "39S(TTTS IH  ) W!$QRSQT"UVVWD  *	Q4QC89!2> 36a& :#..01 2A$JJ s^5O$PPPU*	Qs{   ;D/L; *L=8L; 6L L; 1L; :L; 
B0L; ;L; 
LL; 
L8 L3.L; 3L88L; ;
NANNNz/generate-pdf/<quote_id>c                 N&    SSK nSSKnSSKnSSKnSSKnSSKnSSKJnJn  SSK	J
n	  SSKJn
  SSKJn  SSKJn  SSKJn  [%        S	5        [%        S
5        [%        S	5        UR&                  " 5       n[%        S5        [%        UR(                  " USSS95        Sn [*        R,                  " S5      n[*        R,                  " S5      nU(       a  SSKJn  U" 5        nUR/                  5        nUR1                  SU5        UR3                  5       nU(       a
  US   (       d"  UR1                  SU5        UR3                  5       nSSS5        SSS5        W(       a  US   (       a  US   nU(       d	  U(       a  Un[%        SU=(       d    S 35        [7        UR9                  5       5      nUR:                  R=                  S5      nU S3n[7        UR9                  5       5      nUR:                  R=                  S5      nU S3nUR>                  nUR@                  RC                  USSSS5      nURE                  USS9  SSKnUR@                  RC                  USU S35      n[G        US S!S"9 nURH                  " UUSSS#9  SSS5        [%        S$U 35        UR-                  S%U 5      RK                  S&5      S   n[%        S'U 35         U" 5        nUR/                  5        nUR1                  S(U5        UR3                  5       nUS   (       d  S)OUS   S)-   nSSS5        SSS5        [%        S*W 35        U S&U 3n [%        S,U  35        [7        U5      n!U n"[%        S-U! 35        [%        S.U" 35        S/U S0U S1U S23n#UR@                  RC                  UU#5      n$[%        S3U S0U S235        UR@                  RC                  US4SSS55      n%[%        S6U 35        [%        S7U% 35        [%        S8UR@                  RM                  U%5       35        UR@                  RM                  U%5      (       d#  S9U% 3n&[%        S:U& 35        [O        SU&S;.5      S<4$ [%        S=U% 35        [%        S>5        URQ                  S?5      n'U'(       dd  [%        S@5        SASBUR@                  RS                  SC5      /n(U( H5  n)UR@                  RM                  U)5      (       d  M%  U)n'[%        SDU) 35          O   U'(       a   UR@                  RM                  U'5      (       d   SEn&[%        S:U& 35        [O        SU&S;.5      S<4$ [%        SFU' 35        [%        SGU 35        [%        SHU$ 35        [%        SIU 35        [%        SJ5        URU                  U'U%UU$U/URV                  URV                  SS!SKUR@                  RY                  U%5      SL9n* U*R[                  SMSN9u  n+n,U*R\                  n-U+(       a  [%        SOU+ 35        U,(       a  [%        SPU, 35        U-S:w  a,  U,(       a  U,OSQn&[%        SRU- 35        [O        SSSU& 3S;.5      S<4$ UR@                  RM                  U$5      (       d  [%        STU$ 35        [O        SSUS;.5      S<4$ [%        SVU$ 35        [%        SWUR@                  R_                  U$5       SX35        [%        S[5        [%        S\U! SU" S35        URe                  S]5      n.URe                  S^5      n/URe                  S_5      n0S`SSaU!U"/n1[%        SbScRC                  U15       35         URg                  U.5      n2U2Ri                  U/U05        [%        Sd5        Sen3U2Rk                  U35        [%        SfU3 35        Sn4U1 H-  n5 U2Rk                  U55        [%        SgU5 35        U5S:X  a  Sn4M-  M/     U2Ro                  5       n6[%        Sp5        [%        SqU6 35        U2Rq                  5         [%        Ss5        StU! SU" S3n7SuU! SU" S3n8[G        U$Sv5       nU	" US/U S1U S23SwSx9n9S/U S0U 3n:U
" U9U:U7U85      n;U;Sy   (       d  [%        SzU;S{    35        [%        S|5        S}n<S~n=[G        U$Sv5       n>U	" U>S/U S1U S23SwSx9n?U
" U?U:U<U=5      n;U;Sy   (       d%  [O        SU;S{   S;.5      S4sSSS5        sSSS5        $  SSS5        U;S   n@[%        SU@ 35        SSS5        [%        S5         [u        UR-                  SS5      5      nA[u        UR-                  SS5      5      nB[u        UR-                  SS5      5      nC[u        UR-                  SS5      5      nDUAUB-
  nEUCUB-
  nF0 nG U" 5        nUR/                  5        nUR1                  SUR-                  S5      5        UR3                  5       nHUH(       a  WHS   UHS)   [u        UHS   5      S-  S.nGO&UR-                  SS5      UR-                  SS5      SS.nGSSS5        SSS5        [%        S5        UR-                  SS5      nIUInJ U" 5        nUR/                  5        nUR1                  SUI5        UR3                  5       nKUK(       a  WKS   (       a  WKS   nJSSS5        SSS5        [%        SWI ScWJ 35        [v        Rx                  " UR-                  S%5      5      nLULR-                  S5      nMULR-                  S5      nNULR-                  S5      nO[%        SUN 35        [%        SUM 35        [%        SUO 35        0 SU _SU_SUR-                  S%5      _SUR-                  SS5      _SUR-                  SS5      _SUR-                  SS5      _SUR-                  SS5      _SUR-                  SS5      _SUR-                  SS5      _SUR-                  SS5      _SUR-                  SS5      _SUR-                  SS5      _SULR-                  S5      _SWA_SWB_SWC_SWD_WEWFWGS   UGS   UGS   WJWIUR-                  SS)5      [{        UR-                  S/ 5      5      W@UR|                  " 5       R                  S5      S.EnPSU$SU S0U S23SS./nQS/nRU(       a   WRR                  U5        [%        SU 35        O[%        S5        WM(       a&  WMWR;  a   WRR                  WM5        [%        SUM 35        O!WM(       a  [%        SWM 35        O[%        S5        [%        SWR 35        U" SSU SU SUR-                  SS5       3SWPWQSUR0S9nSUSS   USS{   USS   S   S.nTUSS   (       a.  [%        S5        [%        SWSS   S    35        [%        SU 35        O[%        SWSS{    35         SSKCnVUVR                  S)5         UR@                  RM                  U$5      (       a  [%        SU$ 35        [%        SUR@                  RM                  U$5       35        [%        S[        UR                  U$5      R                  5      SS  35        UR                  U$5        [%        SU$ 35        O[%        SU$ 35          UR@                  RC                  USU S35      nUR@                  RM                  U5      (       a  UR                  U5        [%        SU 35        [%        S	5        [%        S5        [%        S	5        [O        SW@U8USS.WTE5      S4$ ! , (       d  f       GN= f! , (       d  f       GN= f! [4         a  n[%        SU 35         SnAGN~SnAff = f! , (       d  f       GN= f! , (       d  f       GN= f! , (       d  f       GN!= f! [4         a$  n[%        S+[7        U5       35        S)n SnAGN?SnAff = f! UR`                   a.    U*Rc                  5         [%        SY5        [O        SSZS;.5      S<4s $ f = f! URl                   a    U4(       dL  ShU5 SiU2Ro                  5        SU5 3n&[%        SjU& 35        U2Rq                  5         [O        SU&U5Sk.5      S<4s s  $ [%        SlU5 35         U2Rs                  U55        U2Rk                  U55        [%        SmU5 35         GM  ! [4         aM  nSnU5 So[7        U5       3n&[%        SjU& 35        U2Rq                  5         [O        SU&S;.5      S<4s SnAs s  $ SnAff = ff = f! [4         a6  nSr[7        U5       3n&[%        S:U& 35        [O        SU&S;.5      S<4s SnA$ SnAff = f! , (       d  f       GNe= f! , (       d  f       GN\= f! , (       d  f       GNN= f! , (       d  f       GNX= f! [4         a?  n[%        SU 35        UR-                  SS5      UR-                  SS5      SS.nG SnAGNSnAff = f! , (       d  f       GN== f! , (       d  f       GNG= f! [4         a  n[%        SU 35         SnAGNWSnAff = f! [4         aH  n[%        S[7        U5       35        SSKAnUUUR                  5         SS[7        U5       3SS.nT SnAGNSnAff = f! [         a$  n[%        SU 35        [%        S5         SnAGN+SnAf[4         a6  n[%        S[7        U5       35        SSKAnUUUR                  5          SnAGNiSnAff = f! [4         a"  n[%        S[7        U5       35         SnAGN8SnAff = f! [4         aE  n[%        SU 35        SSKAnUUUR                  5         [O        S[7        U5      S;.5      S<4s SnA$ SnAff = f)u   
Genera el PDF de la cotización, lo sube a FTP en estructura de carpetas y envía por email
Ruta final: /api/reception/generate-pdf/<quote_id>
r   N)r   r   )FileStorage)subir_archivo_ftp_desde_requestr   r   )get_connectionzP================================================================================u+   🚀 INICIANDO GENERACIÓN DE PDF CON EMAILu$   🧠 Datos recibidos para genera PDF   F)indentensure_asciiuser_idemailz+SELECT Email FROM Profiles WHERE UserID = ?a  
                                    SELECT P.Email
                                    FROM Users U
                                    JOIN Profiles P ON P.ProfileID = U.ProfileID
                                    WHERE U.UserID = ?
                                u"   📧 Email del creador detectado: zNo disponibleu1   ⚠️ No se pudo resolver el email del creador: /z)/Ventas/Cotiz/Recepcion/preview-quotationrR   rS   rT   rU   T)exist_okrV   rW   wrY   rZ   )r   r~   u!   💾 Datos temporales guardados: 	CostingID-u/   
📊 Obteniendo versión de cotización para: zu
                            SELECT MAX(Version) FROM Q_QuotationHead WHERE QuotationNum = ?
                        rP   u"   📊 Versión calculada desde BD: u5   ⚠️ Error al obtener versión, usando versión 1: u   ✅ QuoteID construido: u   📁 Carpeta base: u   📁 Carpeta versión: cotizacion__V_z.pdfu    📄 Nombre del PDF: cotizacion_puppeteer_pdfzPreviewCotizacion.jsu   📂 Base dir: u   📄 Script path: u   📄 Script exists: z&Script de Puppeteer no encontrado en: u   ❌ rB   r$   u   ✅ Script encontrado: u   
🔍 Buscando Node.js...nodeuF   ⚠️ Node.js no encontrado con shutil.which, buscando manualmente...z C:\Program Files\nodejs\node.exez&C:\Program Files (x86)\nodejs\node.exez~\AppData\Roaming\npm\node.exeu     ✅ Encontrado: z?Node.js no encontrado. Instala Node.js desde https://nodejs.orgu   
✅ Usando Node.js desde: u   
🌐 URL de vista previa: u   💾 Ruta de salida: u   🎫 Token: u   
🚀 Ejecutando Puppeteer...ignore)stdoutstderrtextr[   errorscwdZ   )timeoutu   
📋 Puppeteer stdout:
u   
⚠️ Puppeteer stderr:
z Error desconocido al generar PDFu"   
❌ Puppeteer falló con código zError al generar PDF: u   ❌ PDF no generado en: z$El PDF no fue generado correctamenteu   ✅ PDF generado exitosamente: u   📦 Tamaño del archivo: z bytesu1   ❌ Timeout: Puppeteer tardó más de 90 segundosu0   Timeout: La generación del PDF tardó demasiadou=   
🗂️ Verificando/Creando estructura de carpetas en FTP...u1   📊 Estructura a crear: /Cotizaciones_Generales/FTP_HOSTFTP_USERFTP_PASSfileCotizaciones_Generalesu!   📁 Carpetas a crear/verificar: z -> u   ✅ Conectado a FTPz$/domains/sycelephant.com/public_htmlu   📂 Ruta inicial: u     ✅ Carpeta existente: zError: La carpeta requerida 'z&' no existe en el servidor FTP. Ruta: u     ❌ )r?   r!   carpeta_faltanteu     📁 Creando carpeta: u     ✅ Carpeta creada: zError al crear carpeta '': u=   ✅ Estructura de carpetas FTP verificada/creada exitosamenteu   📂 Ruta final en FTP: zError al trabajar con FTP: u   
📤 Subiendo PDF a FTP...zH/domains/sycelephant.com/public_html/file/Ventas/Cotizaciones_Generales/z/Ventas/Cotizaciones_Generales/rbQuotationPDF)streamfilenamenameexitou   ❌ Error al subir a FTP: mensajeuC   ⚠️ Intentando método alternativo sin estructura de carpetas...z1/domains/sycelephant.com/public_html/file/Ventas/z/Ventas/rA   url_webu   ✅ PDF subido exitosamente: u#   
📧 Preparando envío de email...	SalePriceAmountTotalAmountDiscountPercentz
                                SELECT TaxCode, FrontES, TaxAmount 
                                FROM Q_TaxRate 
                                WHERE TaxCode = ?
                            TaxCoded   )codigonombre
porcentajezN/Au+   ⚠️ Error al obtener info del impuesto: u-   
👤 Obteniendo información del vendedor...CurrencyCodeUSDzs
                                SELECT FrontES FROM Q_Currency WHERE CurrencyCode = ?
                            u   💱 Moneda para email: u,   ⚠️ No se pudo obtener nombre de moneda: r   telefonou   ✅ Vendedor encontrado: u   ✅ Email vendedor: u   ✅ Teléfono vendedor: quotation_idversion
costing_idcaso_costeoCaseCostcliente_nombreCRM_ContactNameClientetipo_contactoCRM_ContactTypeoportunidad_crmCRM_OpportunityNumbercliente_emailCRM_ContactEmailcliente_telefonoCRM_ContactNumbercliente_ciudadCRM_ContactCitycliente_estadoCRM_ContactStatecliente_paisCRM_ContactCountryvendedor_asignadoprecio_listaprecio_ofertaprecio_totaldescuento_porcentajer   r   OvercostFactorQuotationLinesz%d/%m/%Y %H:%M)monto_descuentomonto_impuestoimpuesto_codigoimpuesto_nombreimpuesto_porcentajemonedamoneda_codigofactor_sobrecostototal_lineaspdf_urlfecha_generacionlocalCotizacion_zapplication/pdf)tiporutar   mimetypezjesuscadena27@hotmail.comu0   ✅ Email del creador agregado a destinatarios: u6   ⚠️ No se agregó email del creador (no disponible)u1   ✅ Email del vendedor agregado a destinatarios: u0   ℹ️ Email del vendedor ya está en la lista: u7   ⚠️ No se agregó email del vendedor (no disponible)u   📧 Destinatarios TO finales: z0Emails/Ventas/Cotiz/RecepcionCotizacionMail.htmlu   📋 Nueva Cotización z - Vz - i  TO)template_pathasuntomail_list_idtemplate_dataarchivos_adjuntosdestinatarios_adicionalesr?   destinatariostotal_destinatarios)email_enviadoemail_mensajeemail_destinatariosu   ✅ Email enviado correctamentez   Destinatarios: u.   ⚠️ Advertencia: No se pudo enviar email - u   ❌ Error al enviar email: zError al enviar email: u   🔍 Intentando eliminar: u   🔍 Archivo existe: u   🔍 Permisos: u    ✅ Archivo temporal eliminado: u   ⚠️ Archivo no existe: u#   ❌ Error de permisos al eliminar: u;   💡 El archivo podría estar siendo usado por otro procesou(   ❌ Error al eliminar archivo temporal: u)   🗑️ Archivo temporal JSON eliminado: u2   ⚠️ No se pudo eliminar archivo temporal JSON: u#   ✅ PROCESO COMPLETADO EXITOSAMENTEz5PDF generado, subido y enviado por email exitosamente)r?   r   pdf_ruta_ftpr   messagerO   u   
❌ ERROR CRÍTICO: )Jr`   
subprocessuuidshutilftplibra   rb   r   r   werkzeug.datastructuresrz   App.Subir_Archivor{   #App.Utilities_module.MailManagementr   r   Consultas_SQL.conexionr|   r4   rC   dumpsr   rE   cursorexecutefetchoner'   ro   uuid4host_urlrstripre   rc   rd   makedirsrg   dumpsplitrf   r   which
expanduserPopenPIPEdirnamecommunicate
returncodegetsizeTimeoutExpiredkillgetenvFTPloginr   
error_permpwdquitmkdfloatr   get_seller_infor_   nowstrftimeappendrm   rn   timesleepoctstatst_moderk   PermissionError)Wquote_idr`   r   r   r   r   ra   r   r   rz   r{   r   r   r|   rF   
user_emailr   session_emailconnr   rowr)   rQ   base_urlpreview_urlbase_dirrr   rs   rt   r   version_resultr   quote_id_correctocosting_num_basequote_id_folderoutput_filenameoutput_pathscript_path	error_msg	node_pathpossible_pathsrc   processr   r   return_codehost_ftpusuario_ftp   contraseña_ftpcarpetas_estructuraftpcurrent_pathpuede_crearcarpetaruta_final_ftpruta_ftp_completacarpeta_relativapdf_fileitemresultado_ftpruta_ftp_simplecarpeta_simplef2	pdf_file2r   r   r   r   r   r   r   impuesto_infotax_rowr   moneda_nombremoneda_resultvendedor_infovendedor_emailvendedor_nombrevendedor_telefonor   r   destinatarios_toresultado_email
email_inform   r  sW                                                                                          r*   !generate_quotation_pdf_controllerOregistrar_rutas_recepcion_cotizacion.<locals>.generate_quotation_pdf_controller)  s   y	E2;IS)=(O?@(O ##%D 89$**T!%@A J O!++i0 'G 4E')T![[]f"NN+XZab"(//"3C#&c!f & 0$
 &-!. '-oo&7 + *  s1v%(V
 "m!.J::;X:YZ[ 

%E ''..s3H%J&OPK 

%E ''..s3H%J&OPK #,,Hh%7SJKK
TK2 WW\\*
5'6OPNncG<		$a@ =5n5EFG
 ((;9??DQGK D[MRS#%& ((* *0):+9!+<!.QRBSVWBW ' & :7)DE $/-q	 :,->,?@A  #;//O'(8'9:;+O+<=> !,K=7)1UG4PO'',,z?CK4[MG9DQR '',,/8W>TK OH:./&{m45()D(EFG77>>+..D[MR	YK()59EFKK+K=9: ./V,I^_7=GG&&'HI" +Dww~~d++$(	 24&9:	 + BGGNN9$=$=]	YK()59EFKK0<=0>?)+78L()23 !&&Kk5I!! GGOOK0 ' Gu!(!4!4R!4!@%006vh?@8AB!#*06XI?}MN"uAWXaWb?c#degjjjww~~k224[MBC"u?e#fgilll7}EF2277??;3O2PPVWX RSEFVEWWXYhXiijklyy,H))J/K ii
3O $*85MO_ap"q5fkkBU6V5WXY:Ljj*		+7+,  F%+L>:; $2G!\( 9'CD #h.*.K /  3H "%UW00@AB
 01 #kk{j||}  N  ~O  OP  !Q!@AQ@RRSTcSddefk4(A&*;-q	F' %[MG9= ?%$	! %W-6}Y7O6PQR_` 'ZO%/Nk40B$/#%'2;-q	%N!/%	 )H% +*	)  -W5#*u}U^G_+`#acf#f 101 )(L  6 1" (	25gY?@U )Z 89j$TXXk1%=> %dhhx&; <$TXXmQ%?@',TXX6G-K'L$ #/">!-!= !#')T![[]f"NN ,  "&)!4	6
 '-oo&7G&.5aj.5aj27
2Cc2I1" /3hhy%.H.2hhy%.H231" + *: FG !% ? -N')T![[]f"NN , !.0 -3OO,=M,q1A0=a0@ + * 4]O4WX "3!B!B488KCX!Y!.!2!27!;"/"3"3H"=$1$5$5j$A!1/1BCD,^,<=>01B0CDE"!"H"!w"! !$((;"7"! "488J#>	"!
 %dhh/@)&L"! $TXX.?%G"! &txx0G'O"! $TXX.@%%H"! '1De(L"! %dhh/@%&H"! %dhh/A5&I"! #DHH-A5$I"! ():):8)D"!  #L!"!" $]#"!$ #L%"!& +,@'"!( (7&4 (5X'>'4X'>+8+F+%2)-2BA)F$'1A2(F$G&(0(?(?@P(QC"!L !( +$/}Bwit"L$5	%! %@#@  $++J7LZLYZRS "n<L&L$++N;MnM]^_#L^L\]^ST78H7IJK"9"T0T'#dhhWhjsNtMuv!%"/&7./	# &5Y%?%4Y%?+:?+KLa+b
 #9-;=./OPe/f.ghiLZLYZJ?[dKeJfgh  JJqM&77>>+..6{mDE1"''..2M1NOPOC0D0L0L,Mbc,R+STUIIk*<[MJK6{mDEU!#jJugU:S!T77>>.11IIn-EnEUVW (O78(O" 0"R    Q +] *)2  OI!MNNO4 =< ' &%  McRSfXVWL ,, uIJ5;mnoqtttuT ",, \  +*GyPvwzw~w~  xA  wB  BC  DK  CL  )MI!F9+"67HHJ#*+0)24;, $ !$	$$ $ "$<WI"FG\ # 0 # 0 %(>wi&H I I#, \.FwisSVWXSYRZ,[	 %yk&: ; #
'.59/U'VX['[ [ [	\)\@  L9#a&B	YK()59EFKKLH 101 )(| +] *)* ! GsKL"&((9e"<"&((9e"<&'%M" +] *) ! NHLMMNJ  3CF8<= ##%%*'>s1vh%G+,
	6 # V;A3?@SUU &@QIJ ##%%&  UJ3q6(STTU$  	E*1#./!us1v>?DD		Es  BAK A {/ {,A{{
A{/ CAK +|?AAK } |9 7|'|9} 5DAK A=AK AAK .B
AK 9A9}< 3=}< 16}< 'A4AK AAC 3'~=?AC )AK AAD7AD	AD	AK &ADAK A8AG" AE AD:&A;AD(!AD:)AE 1AG" AF< AF*)9AF"AF**AF< KAG" AK AG" 'AK >B'AH7 %AK &AH7 4AK 6AAJ& 5AK 
{	{
{,'{/ /
|9|AK |AK 
|$AK '
|6	1|99
}} 
}9}4.AK 4}99AK <;~:7AK 9~::AK =AAB>@AC @ AB>@/0AA#AAC A#
AB:A->AB5B+AB:B,AB>B1AC B5AB:B:AB>B>AC C
ADC+AC<C6ADC7AK C<ADDAK D
AD	DADD
AD%D AK D(
AD7	D2AD:D:
AE	EAE EAG" E	AE E
AFE4AFF
AG" FAFFAG" F
AF'	F"AF*F*
AF9F4AF< F<
AGGAGGAG" GAGGAG" G"
AH4G,=AH/H)AK H/AH4H4AK H7
AJ#IAI IAK I AJ#I-+AJJAK JAJ#J#AK J&
AKJ0AKKAK KAKKAK K
AL$K:ALLAL$LAL$z(/Ventas/Cotiz/Recepcion/BuscarCotizacionc                      [         R                  " 5       n U (       a  SU ;  a  [        SSSS.S.5      S4$ U S   R                  5       n[        R                  SU 35        [        U5      nU(       a@  UR                  S	S
5      S;   a*  [        R                  SU S35        [        SUSS.5      S4$ U(       aD  UR                  S	S
5      n[        R                  SU SU 35        [        SSU 3SSS.S.5      S4$ [        R                  SU S35        [        SSU S3SSS.S.5      S4$ ! [         a>  n[        R                  S[        U5       3SS9  [        SS S!S"S#.S.5      S$4s S%nA$ S%nAff = f)&uO   Busca y recupera todos los datos de una cotización finalizada por ingeniería.cotizacion_idFu#   ID de cotización no proporcionado.INVALID_REQUESTr   coderB   rA   u!   Buscando cotización completada: StatusIngenieria	PENDIENTE)
COMPLETADO
FINALIZADA   Cotización u#    encontrada y lista para revisión.Tu'   Cotización lista para revisión final.)r?   rF   r   rO   u    no está lista. Estatus: uJ   La cotización aún no ha sido finalizada por Ingeniería. Estado actual: infoCOTIZACION_PENDIENTE)r   
alert_typerP  i  z no encontrada en el sistema.u   El ID de cotización 'u   ' no existe o no está activo.warningCOTIZACION_NOT_FOUNDr"   u#   Error en búsqueda de cotización: exc_infou+   Error interno del servidor en la búsqueda.INTERNAL_ERRORr!   r   rP  rX  r$   N)r   rC   r   striploggerrV  r   rE   rY  r'   r!   ro   )rF   rM  cotizacion_completarL   r)   s        r*   buscar_cotizacion?registrar_rutas_recepcion_cotizacion.<locals>.buscar_cotizacionn  s   +	j##%D?$65Gl  wH  <I   J  K  MP  P  P 1779MKK;M?KL #=]"K"':'>'>?QS^'_c'l=/9\]^#/H   	 
 %,001C[Qm_<VW]V^_`$%opvow#x&, 6     m_<YZ[$%;M?Jh#i&/ 6      	jLL>s1vhGRVLWuCp  {K  [b  8c  d  e  gj  j  j	js0   4D0 A<D0 4A
D0 ?0D0 0
E8:3E3-E83E8z(/Ventas/Cotiz/Recepcion/EnviarCotizacionc                    > [         R                  " S5      n U (       d  [        SSSS.S.5      S4$  [        R                  " 5       nU(       a  SU;  a  [        SS	S
S.S.5      S4$ US   nUS   nUS   nUS   n[
        R                  SU 35        [        X$U 5      nUS   (       d  [        SSUS    3SS.S.5      S4$ [        X#U 5      nUS   (       d  [        SSUS    3SS.S.5      S4$ [        X%U 5      nUS   (       d  [        SSUS    3SS.S.5      S4$ [        X U5      n	U	S   (       d  [        SSU	S    3SS.S.5      S4$ U	R                  S5      (       a  T" X!X	S   5        [
        R                  SU S35        [        SSU S3X)R                  S5      S .S!.5      S"4$ ! [         a>  n
[
        R                  S#[        U
5       3SS$9  [        SS%S&SS'.S.5      S4s S(n
A
$ S(n
A
ff = f))uL   Procesa la cotización final, actualiza el estado y notifica al cliente/CRM.r   FzUsuario no autenticadoNOT_AUTHENTICATEDrO  rB   i  rM  u!   Datos de cotización incompletos.rN  rA   financieroslineastiempo_condicionesu5   Iniciando proceso de finalización para Cotización: r?   u   Error al actualizar líneas: r   rY  )r   rX  r$   z'Error al actualizar datos financieros: z*Error al actualizar tiempo y condiciones: u    Error al finalizar cotización: r!   r   rU  z# finalizada y enviada exitosamente.T   La cotización z4 ha sido enviada al cliente y actualizada en el CRM.)rM  r   )r?   r   rF   rO   u%   Error inesperado en el envío final: r[  u.   Error interno del servidor en el envío final.r]  r^  N)r   rE   r   r   rC   r`  rV  r   r   r   r   r'   r!   ro   )r   rF   rM  rf  rg  rh  resultado_lineasresultado_financieroresultado_tiemporesultado_finalr)   enviar_correo_cliente_v2s              r*   enviar_cotizacion?registrar_rutas_recepcion_cotizacion.<locals>.enviar_cotizacion  sd    ++i(uC[ex7yz{  ~A  A  A1	m##%D?$65Gj  uF  <G   H  I  KN  N  N 1M}-K(^F!%&:!;KKOP]_`
  <MSZ[#I.5Ifgw  yB  hC  gD  HE  U^  <_   `  a  cf  f  f $A]d#e '	25Ip  rF  GP  rQ  qR  HS  cl  <m   n  o  qt  t  t  ?}bij#I.5Is  uE  FO  uP  tQ  HR  bk  <l   m  n  ps  s  s <MTXYO"9-5Iijy  {D  kE  jF  HG  W^  <_   `  a  cf  f  f ""9--(gW`GabKK,}o5XYZ,]O;op*7DWDWXaDbc  	   	mLL@QITXLYuCs  ~N  ^e  8f  g  h  jm  m  m	ms=   4F1 (AF1 .F1 2.F1 !.F1 A F1 1
G9;3G4.G94G9z	/getTermsc                    > [         R                  S5         [        5       n U (       d$  [         R                  S5        [	        SS05      S4$ [
        R                  " U [        S9nTR                  USSS	9n[         R                  S
[        U 5       S35        U$ ! [         a1  n[         R                  SU 35        [	        SS05      S4s SnA$ SnAff = f)u   
Endpoint para obtener todos los tipos de términos y condiciones activos
desde la tabla Q_TermsType y devolverlos en formato JSON.
uJ   📥 Solicitud recibida para obtener los tipos de términos y condiciones.u:   ⚠️ No se encontraron registros activos en Q_TermsType.r!   z$No se encontraron registros activos.r"   defaultrO   application/jsonrq   rL   r   u   ✅ z# registros devueltos correctamente.u+   ❌ Error inesperado al obtener términos: u,   Ocurrió un error inesperado en el servidor.r$   N)r`  rV  r   rY  r   ra   r   r   response_classr_   r'   r!   )resultado_dictjson_responserq   r)   apps       r*   get_TermsType_JSON_controllerKregistrar_rutas_recepcion_cotizacion.<locals>.get_TermsType_JSON_controller  s     	`a	[/1N "[\)OPQSVVV !JJ~OM ))&+ * H
 KK$s>233VWXO 	[LLFqcJKG%STUWZZZ	[s$   4B AB 
C%&CCCz/<string:cotizacion_id>rM  c                   > [         R                  SU  35         [        U 5      nU(       d'  [         R                  SU  35        [	        SS05      S4$ [
        R                  " U[        S9nTR                  USSS	9n[         R                  S
U  35        U$ ! [         a4  n[         R                  SU  SU 35        [	        SS05      S4s SnA$ SnAff = f)u   
Endpoint para obtener los datos de una cotización en formato JSON.
Responde con los datos en caso de éxito, o con un código de error apropiado.
u0   Recibida solicitud para obtener la cotización:    Cotización no encontrada: r!   u   Cotización no encontradar"   rr  rO   rt  ru  u'   Respuesta exitosa para la cotización: u*   Error inesperado al procesar cotización 'r   u+   Ocurrió un error inesperado en el servidorr$   N)r`  rV  r   rY  r   ra   r   r   rv  r'   r!   )rM  rw  rx  rq   r)   ry  s        r*   *get_Quote_JSON_BussinessCentral_controllerXregistrar_rutas_recepcion_cotizacion.<locals>.get_Quote_JSON_BussinessCentral_controller  s     	F}oVW	Z<]KN "!<]OLM)DEFKK
 !JJ~OM ))&+ * H
 KKA-QRO 	ZLLEm_TWXYWZ[\G%RSTVYYY	Zs$   8B AB 
C")CCCz/<string:cotizacion_id>/sendc                    [         R                  SU  35         [        U 5      nU(       d>  [         R                  SU  35        [	        SSU R                  S5      S    S3S.5      S	4$ [        [        R                  5      n[        R                  " 5       nUR                  nS
SS.nUR                  S:X  a+  [         R                  SU  S35        UR                  U5      nO[         R                  SU  S35        [         R                  SU  S35        [	        S
SU R                  S5      S    S3US.5      S4$ ! [        R                  R                   a  n[         R                  SU R                  S5      S    SUR                   R"                   35        [	        SSUR                   R"                  S.5      UR                   R$                  4s SnA$ SnAf[        R                  R&                   a2  n[         R                  SU 35        [	        SSS.5      S4s SnA$ SnAf[(         aF  n[         R                  SU R                  S5      S    SU 3S S!9  [	        SS"S.5      S#4s SnA$ SnAff = f)$uv   
Endpoint para enviar una cotización desde la BD local al CRM.
Se usa con método POST (por ejemplo, desde Postman).
u4   Recibida solicitud POST para enviar la cotización: r}  r!   ri  r   r   z' no fue encontrada en la base de datos.)rL   r   r"   r?   u    MODO PROTOTIPO: Envío simulado.Fu   Enviando cotización 'z' al CRM...u1   MODO PROTOTIPO: Simulando envío de cotización 'z	' al CRM.u   Cotización 'z' enviada exitosamente al CRM.rU  z enviada exitosamente al CRM.)rL   r   crm_responserO   zError HTTP al enviar 'r   u   El CRM rechazó la solicitud.)rL   r   r:   Nu#   Error de comunicación con el CRM: u"   Error de comunicación con el CRM.i  u+   Error inesperado al enviar la cotización 'Tr[  u'   Error interno al enviar la cotización.r$   )r`  rV  r   rY  r   r   r   r   configConfig	PROTOTIPO
send_quoterequests
exceptions	HTTPErrorr!   rq   r   status_codeRequestExceptionr'   )rM  quote_data_to_sendcrm_managerconfigurationvalorr  r)   s          r*   send_quote_controllerCregistrar_rutas_recepcion_cotizacion.<locals>.send_quote_controller)  s    	J=/Z[2	k!@!O &!<]OLM%!01D1DS1I!1L0MMtu     %[%7%78K"MMOM!++E&/<^_L &&%/4]O;OP*556HIOP]^ghi KK-6TUV#)-*=*=c*B1*E)FFcd ,  	  "",, 	'LL1-2E2Ec2J12M1NcRSR\R\RaRaQbcd!:::??  

&&	' ' ""33 	fLL>qcBCg:^_`beee 	kLLF}GZGZ[^G_`aGbFccfghfijuyLzg:cdegjjj	ksJ   AD= *CD= =I;A9GI;!I;;'H("I;(I;5;I60I;6I;rF   r   r   c                   >  UR                  S0 5      R                  SS5      nUR                  S0 5      R                  SS5      nUU U[        R                  " 5       R                  S5      S.nUnT
R                  R                  S5      (       a  T
R                  R                  S	5      n[        S
SU  3U/US9nUS   (       d&  [        R                  SU SUS    35        SUS   S.$ [        R                  SU 35        SS0$ ! [         a9  n	[        R                  S[        U	5       35        S[        U	5      S.s Sn	A	$ Sn	A	ff = f)u5   Simula el envío de correo de cotización al cliente.oportunidadr   zcorreo_prueba@igsa.com.mxr   zCliente Estimadoz%d/%m/%Y)r   rM  r   fecha_envioEMAIL_PROTOTYPE_MODEEMAIL_PROTOTYPE_TOADRESSz-Emails/Ventas/Cotiz/CotizFinalClientMail.htmlu   Cotización Finalizada - ID )r   r   to_listr   r?   z"Error al enviar correo al cliente z: r   F)r?   r   u7   Correo de cotización enviado exitosamente al cliente: Tu4   Error en el proceso de envío de correo al cliente: N)rE   r   r  r  r  r   r`  rY  rV  r'   r!   ro   )rM  rF   r   r   r   cliente_namer   destinatario	resultador)   ry  s             r*   rn  Fregistrar_rutas_recepcion_cotizacion.<locals>.enviar_correo_cliente_v2j  sU   %	9 !HH]B7;;<NPklM88M26::;LN`aL #/!."'||~66zB	M  -Lzz~~455#&::>>2L#ML 0M5m_E%+	I Y'!CM?RTU^_hUiTjkl#(Yy5IJJKKQR_Q`abt$$ 	9LLOPSTUPVxXY$Q88	9s$   C)D	 -D	 	
E.EEE)routeintro   r   )ry  mail_BASE_ROUTEr+   r0   r6   r;   rH   rw   rJ  rb  ro  rz  r~  r  rn  s   `              @r*   $registrar_rutas_recepcion_cotizacionr  !   s   +K
 	YY+89E7YKWc W LW$ 	YY+f%wY7	W 8	W 	YY+k*UGY<
W =
W 	YY+@AE7YS
WC 
W T
W 	YY+/06(YCi Di$ 	YY+01FI;NYO\Q P\Q| 	YY+67&YJ~E K~EH 	YY9F8YL-j M-jf 	YY9F8YL7m M7mv 	YY+i(5'Y:[ ;[D 	YY+56YH#Z# #Z I#ZN 	YY+:;fXYN9kS 9k O9k@'9 '94 '9# '9X[ '9 '9    )#rb   r   r   r   r   r   r   r	   	functoolsr
   loggingra   r   typingr   r   r  r  "App.Utilities_module.CRMManagementr   ,Consultas_SQL.Ventas.Cotiz.RecepcionCotizSQLr   r   r   r   r   r   r   r   r   r   r   	getLoggerr`  r   r  r*   <module>r     sZ    ] \ \       :	 	 	 K G 			1	2p9r  