a
    0i                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
mZ d dlmZmZmZ d dlmZmZ e dd	Zed
krene
ZdZdZdZedd edd edd edd G dd dZdddZdd ZdS )    N)BytesIO)datetime)jsonify)DevelopmentConfigProductionConfig)obtener_catalogo_validacionguardar_log_validacionobtener_cantidades_componentes)ValidadorTiposDatoslimpiar_dataframe	FLASK_ENVdevelopment
productionzhttps://igsa1-my.sharepoint.com/personal/alexis_moreno_igsa_com_mx/_layouts/15/download.aspx?share=EStyzV5jqTRGqhyxo4jfzmIBYCfPhbrU4xMICcpWqMSqiwZScoreV2zdisplay.max_columnszdisplay.max_rowszdisplay.widthzdisplay.max_colwidth2   c                   @   sx   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )ValidadorScoreu?   
    Clase principal para manejar la validación del Score
    c                 C   sB   t | _t| _t| _|  | _d | _d | _	g | _
t d| _d S )Nz%Y%m%d_%H%M%S)url_sharepoint_globalurl_sharepointnombre_hoja_globalnombre_hojanombre_tabla_excel_globalZnombre_tabla_excel_obtener_ruta_descargaruta_descargacatalogo_validaciondf_scoreZerrores_validacionr   nowstrftime	timestamp)self r   G/var/www/html/src/App/SupyCtrol_Module/IngenieroControl/ValidarScore.py__init__&   s    
zValidadorScore.__init__c                 C   s4   t dkrd}ntjt dd}tj|dd |S )u   
        1.2 Configura la ruta de descarga según el ambiente
        
        Returns:
            str: Ruta donde se guardará el archivo
        r   z)/var/www/elephant/temp/score_validacionestempZscore_validacionesT)exist_ok)r   ospathjoingetcwdmakedirs)r   rutar   r   r   r   0   s
    z%ValidadorScore._obtener_ruta_descargac              
   C   sv   z8t  | _| jstd W dS tdt| j d W dS  typ } z tdt|  W Y d}~dS d}~0 0 dS )u   
        1.3 Consulta la tabla CM_DataTypeValidator y crea el diccionario
        
        Returns:
            bool: True si se inicializó correctamente, False en caso contrario
        u5   Error: No se pudo obtener el catálogo de validaciónFu"   Catálogo de validación cargado: 	 columnasTu    Error al inicializar catálogo: N)r   r   printlen	Exceptionstr)r   er   r   r   inicializar_catalogoC   s    z#ValidadorScore.inicializar_catalogoc              
   C   s   zt d tj| jdd}|jdkr:t d|j  W dS d| j d}tj| j	|}t
|d	}||j W d   n1 s0    Y  t d
|  tdkr|   |W S  ty } z t dt|  W Y d}~dS d}~0 0 dS )z
        2. Descarga el archivo Excel desde SharePoint
        
        Returns:
            str: Ruta del archivo descargado o None si hubo error
        z'Descargando archivo desde SharePoint...   )timeout   u   Error al descargar: código NScore_.xlsxwbzArchivo descargado: r   zError al descargar Excel: )r*   requestsgetr   status_coder   r#   r$   r%   r   openwritecontentr   _limpiar_archivos_antiguosr,   r-   )r   responseZnombre_archivoZruta_completafr.   r   r   r   descargar_excelX   s"    
*zValidadorScore.descargar_excelc              
   C   s  zt  }|j}|j}|dkr4dd|  }|d }n|d }|}| |d}t| j}|D ]t}|dr^|dr^zJ|	dd dd	 }	|	|k rtj
| j|}
t|
 td
|  W q^   Y q^Y q^0 q^W n8 ty } ztdt|  W Y d}~n
d}~0 0 dS )z;
        2.4 Elimina archivos anteriores a 3 meses
                 Z02dr3   r4   _N   zArchivo antiguo eliminado: z$Error al limpiar archivos antiguos: )r   r   monthyearr#   listdirr   
startswithendswithsplitr$   r%   remover*   r,   r-   )r   Zfecha_limiteZ
mes_actualt   año_actualZ
mes_limitet   año_limiteZfecha_limite_strZarchivosZarchivoZfecha_archivoruta_archivor.   r   r   r   r<   z   s.    

z)ValidadorScore._limpiar_archivos_antiguosc           $      C   s  ddl m} ddlm} g }ztd td td td td|  td	 ||d
d}td td|j  td| j d | j|jvrtd| j d td|j  |  |W S || j }td td|j  td|j	  td|j
  td i }t|d ddD ]$\}}	|	jr&t|	j ||< q&tdt| d td t| dd D ] \}
}td|
d d!|  q|t|d"krtd#t|d"  d$ td% td& td d}d}d'}t|jd(d)d(dD ]\}}|d7 }||krtd*d+  td,| d-|  td+  d}d}d}td. t|dd/ ddD ]\}}	||d0| }|	j}|	j}|	j}|du s|d1krd2}|d7 }nt|dd3 }|d7 }||k}|r|d7 }d4}nd5}td6| d7| d8|d9d:|d;d<| d= qlt|}td>| d? td@|  tdA|  tdB|  tdC|  |dkrtdD t|ddD ]\}}	|	j|kr|d7 }||dE| }|	jrt|	jndF}|	j}||||dGdH| dI ||krJtdJ| dK tdL|  tdM|  tdN|  tdO|  n&tdP| dQ| dR| dS| dT| 
 q||kr|dU dkrtdV| dW| dX qtd*d  tdY |  tdZ td*d  td[ td  td\|d]d^   td_| j  td`|  tdat|  tdb|t| dc |dkrtdd|  tde i }|D ]"}|df }||dd ||< qtt| D ] \}} tdg| d!|  dh qtdi t|dD ]<\}!}td6|!djdk|dl dmdn|do d9dn|df   qntdp tdq td d* |W S  ty }" zhtd*d  tdr td  tdst|"  tdt ddl}#|#  td d* |W  Y d}"~"S d}"~"0 0 dS )uu_  
        Detecta errores nativos de Excel usando OpenPyXL
        (como #VALOR!, #REF!, #DIV/0!, #N/A, #NAME?, #NULL!, #NUM!)
        CON PRINTS DETALLADOS PARA DEBUG
        
        Args:
            ruta_archivo (str): Ruta del archivo Excel
            
        Returns:
            list: Lista de errores encontrados en formato estándar
        r   )load_workbook)
TYPE_ERRORe
====================================================================================================uB   🔍 INICIANDO DETECCIÓN DE ERRORES NATIVOS DE EXCEL CON OPENPYXLd====================================================================================================u!   
📂 PASO 1: Abriendo archivo...z	   Ruta: u?      Modo: data_only=False (mantiene fórmulas y detecta errores)T)Z	data_onlyu$      ✅ Archivo abierto correctamenteu      📊 Hojas disponibles: u"   
📄 PASO 2: Seleccionando hoja 'z'...u      ❌ ERROR: Hoja 'z' no encontradaz   Hojas disponibles: u&      ✅ Hoja seleccionada correctamenteu      📏 Dimensiones: u      📊 Filas máximas: u      📊 Columnas máximas: u5   
📋 PASO 3: Leyendo nombres de columnas (fila 1)...rB   )startu      ✅ z columnas detectadasz
   Primeras 10 columnas:N{   z
      Col 2d: 
   z      ... y u    columnas másu>   
🔎 PASO 4: Iniciando búsqueda de errores (desde fila 2)...u9      Se mostrarán las primeras 5 filas de datos en detalle      )Zmin_row
,  ────────────────────────────────────────────────────────────────────────────────────────────────────u
   📍 FILA u    (Fila Excel) - Índice z"   Mostrando primeras 10 columnas:#   ZCol_    [VACÍO]r   u	   ❌ ERRORu   ✓       [z] z<30 = <40z (tipo: )u   
   📊 Resumen fila :u         • Total celdas: u         • Con valor: u         • Vacías: u         • Con ERROR: u,         ⚠️  ¡FILA CON ERRORES DETECTADOS!ZColumna_z#ERROR!ZERROR_EXCELu&   🚫 Error nativo de Excel detectado: filacolumnavalortipo_esperadoerroru   
      🚨 ERROR #z ENCONTRADO:z         Celda: z         Fila Excel: z         Columna: z         Valor: u      ❌ Error #z: Fila z, Columna 'z' [z]: d   z   ... Procesadas z filas (z errores hasta ahora)...u5   🔒 PASO 5: Cerrando workbook y liberando memoria...u%      ✅ Workbook cerrado correctamenteu;   📊 RESUMEN FINAL - DETECCIÓN DE ERRORES NATIVOS DE EXCELu      📄 Archivo: /u      📋 Hoja: u      📏 Filas procesadas: u      📊 Columnas analizadas: u       🔍 Total celdas revisadas: ,u    
   ⚠️  ERRORES DETECTADOS: z#
   Detalle de errores encontrados:rf   u
         • z ocurrencia(s)u#   
   📋 Lista completa de errores:3dz. Fila rd   Z4d | re   u1   
   ✅ NO SE DETECTARON ERRORES NATIVOS DE EXCELu>      🎉 Todas las celdas están libres de errores de fórmulasu4   ❌ ERROR CRÍTICO EN DETECCIÓN DE ERRORES DE EXCEL
   Error: 
   Stack trace completo:)ZopenpyxlrM   Zopenpyxl.cell.cellrN   r*   Z
sheetnamesr   closeZ
dimensionsZmax_rowZ
max_column	enumeratevaluer-   stripr+   listitems	iter_rowsr7   Z	data_typeZ
coordinateappendrJ   sortedr,   	traceback	print_exc)$r   rL   rM   rN   Zerrores_excelr5   wsZcolumnasZcol_idxcellidxnombrecontador_erroresfilas_procesadasZMOSTRAR_PRIMERAS_N_FILASZrow_idxrowZceldas_con_valorZceldas_vaciasZceldas_con_errornombre_columnarf   Z	tipo_datoZ
coordenadaZvalor_mostrarZes_errorZmarcadorZtotal_celdas_filaZvalor_errorZtipos_errorrh   tipoZcantidadir.   rz   r   r   r   _detectar_errores_excel_nativos   s   



0
	
*

8
z.ValidadorScore._detectar_errores_excel_nativosc              
   C   sf  zt d t|}| j|jvrJt d| j d t d|j  W dS tj|| jtd| _dd | jjD | j_t d	t	| j d
t	| jj d t d t d t d t
dt	| j}t|D ]}|d }t dd  t d| d| d t d  | jj|g j}dg|_| jj|  D ]f\}}t|rDd}	n |dkrTd}	nt|dd }	t|j}
t d|dd|	dd|
 d  q*qt d t d! t d t d" t | jj  t d# | j  }||d$k }t	|d$krt |  nt d% t d& W d'S  ty` } z0t d(t|  d$dl}|  W Y d}~dS d}~0 0 dS ))u  
        3. Lee el archivo Excel y carga los datos en un DataFrame
        
        Args:
            ruta_archivo (str): Ruta del archivo a leer
            
        Returns:
            bool: True si se leyó correctamente, False en caso contrario
        zLeyendo archivo Excel...zError: La hoja 'z' no existe en el archivozHojas disponibles: F)Z
sheet_namedtypec                 S   s   g | ]}|  qS r   )rt   .0colr   r   r   
<listcomp>      z-ValidadorScore.leer_excel.<locals>.<listcomp>u   Archivo leído correctamente: z filas, r)   z
======================================================================================================================================================u#   📊 PRIMERAS 5 FILAS DEL DATAFRAMEz======================================================================================================================================================r@   rW   rX   u   FILA NÚMERO u    (índice DataFrame: ra   ZValorz[NULL]r[   r\   Nri     z<45r_   z<55r^   ]zFIN DE PRIMERAS 5 FILASu    
📋 RESUMEN DE TIPOS DE DATOS:u"   
⚠️  RESUMEN DE VALORES NULOS:r   u   ✓ No hay valores nulosz
======================================================================================================================================================
TzError al leer Excel: )r*   pdZ	ExcelFiler   Zsheet_namesZ
read_excelr-   r   columnsr+   minrangeilocTrv   Zisnatype__name__ZdtypesZ	to_stringZisnullsumr,   rz   r{   )r   rL   Z
excel_filenum_filas_mostrarr~   Z
fila_excelZfila_dfZcolumna_nombrerf   Zvalor_formateador   ZnulosZnulos_con_datosr.   rz   r   r   r   
leer_excel  s^    

$


&zValidadorScore.leer_excelc              
   C   s  g }z| j j }t| j }t|t|@ }t|dkrX|ddd d|fW S t	t|t| }t	t|t| }t
d t
d t
d t
d	t|  t
d
 t
d tt	|dD ]\}}t
d|dd|  q|r<t
dt|  t
d t
d t|dD ] \}}t
d|dd|  q|rt
dt|  t
d t
d t|dD ]6\}}| j|d}	t
d| d|dd|	 d qnt
d t
d t
d dg fW S  ty }
 z.|ddt|
 d d|fW  Y d}
~
S d}
~
0 0 dS )u  
        4.1 y 4.2 Valida que al menos existan columnas en común
        YA NO valida orden ni que sean exactamente las mismas
        Solo valida las columnas con Origin = 'Manual'
        
        Returns:
            tuple: (es_valido: bool, errores: list)
        r   
ESTRUCTURAu^   No hay columnas en común entre el Excel y el catálogo (Origin=Manual). Verifica los nombres.)r   mensajeFzQ
================================================================================u   ANÁLISIS DE COLUMNASzP================================================================================u:   
✓ Columnas con Origin='Manual' en común para validar: u'   
Listado de columnas que se validarán:zP--------------------------------------------------------------------------------rB   r   rS   . u>   
ℹ️  Columnas en Excel que NO están en catálogo Manual: u1       (Estas columnas se IGNORAN en la validación)u>   
⚠️  Columnas en catálogo Manual que NO están en Excel: u4       (Estas columnas deberían desactivarse en la BD)zN/Ar`   z (ra   u%   ✓ Validación de estructura exitosazQ================================================================================
TzError al validar estructura: N)r   r   tolistru   r   keyssetr+   rx   ry   r*   rr   r7   r,   r-   )r   errorescolumnas_excelcolumnas_catalogoZcolumnas_comunesZcolumnas_solo_excelZcolumnas_solo_catalogor   r   r   r.   r   r   r   validar_estructura  sX    	
"
z!ValidadorScore.validar_estructurac              
   C   s   zRt | j}t| j\| _}t | j}|| }td| d |||d}||fW S  ty } z&tdt|  dg fW  Y d}~S d}~0 0 dS )u   
        4.3 Aplica limpieza y tratamiento al DataFrame
        
        Returns:
            tuple: (dict estadísticas, list errores_eliminacion)
        u   ✓ Tratamiento aplicado: z filas eliminadas)filas_originalesfilas_finalesfilas_eliminadaszError al aplicar tratamiento: N)r+   r   r   r*   r,   r-   )r   r   Zfilas_eliminadas_detaller   r   estadisticasr.   r   r   r   aplicar_tratamiento_datos   s    


z(ValidadorScore.aplicar_tratamiento_datosc              
      sV  g }zt d t| jj }t| j }||@  t dt    fddtj	D }|rlt d|   D ]r}| j| }t
| j| D ]T\}}tj|||d\}	}
|	s||d |t|rt|dd	 nd
||
d qqpt dt| d |W S  tyP } z:t dt|  dddddt| dgW  Y d}~S d}~0 0 dS )uU  
        5. Valida los tipos de datos SOLO de las columnas que:
        - Existen en el Excel
        - Existen en el catálogo
        - Tienen Origin = 'Manual' (ya filtrado en la consulta SQL)
        - INCLUYE validación de campos obligatorios (NOT NULL)
        
        Returns:
            list: Lista de errores encontrados
        zValidando tipos de datos...z9Columnas a validar (Origin='Manual' y existen en Excel): c                    s   g | ]}| v r|qS r   r   r   Zcolumnas_a_validarr   r   r   W  s   z6ValidadorScore.validar_tipos_datos.<locals>.<listcomp>u*   ⚠️  Columnas obligatorias (NOT NULL): )r   rW   Nr   r\   rc   u   ✓ Validación completada: z errores encontradosz!Error al validar tipos de datos: r   ZSISTEMAr[      Error crítico: )r*   r   r   r   r   r   r   r+   r
   ZCOLUMNAS_OBLIGATORIASrr   Zvalidar_por_tipo_sqlrx   r   notnar-   r,   )r   r   r   r   Z#columnas_obligatorias_en_validacionre   Ztipo_sqlr~   rf   Z	es_validoZmensaje_errorr.   r   r   r   validar_tipos_datos>  sL    


z"ValidadorScore.validar_tipos_datosc                 C   s  zHt |t | }t| jj }t| j }||@ }i }|D ]$}	|	dd}
||
dd ||
< qB|D ]$}	|	dd}
||
dd ||
< ql| jt	
 d|dkrdnd	|r|d
dnd|r|ddnd|r|ddndt |t |t ||t |t |d	|||dd}t|r.|ddnd||t	
 |d d |W S  ty } z tdt|  W Y d}~dS d}~0 0 dS )uE   
        5.3 Genera el reporte consolidado de la validación
        r   r   r   rB   rg   Z	TIPO_DATO%Y-%m-%d %H:%M:%SZEXITOSOZCON_ERRORESr   r   r   )	r   r   r   r   Zcolumnas_catalogo_manualcolumnas_validadastotal_erroreserrores_estructuraerrores_datos)Z
estructuraZdatos)r   Zfecha_validacionestador   errores_por_tipor   r   )Ztotal_filasr   r   r   r   zError al generar reporte: N)r+   r   r   r   r   r   r   r7   r   r   r   r   r   r,   r*   r-   )r   r   r   stats_tratamientor   r   r   r   r   rh   r   reporter.   r   r   r   generar_reporte_consolidado  sR    z*ValidadorScore.generar_reporte_consolidadoc                 C   s  g }zt d t d t d t d t }|jrBt d |W S t dt| d t d t d	t|j  t d
 |jD ]}t d| d|| j  qt dd  t d t d tdt|}t|D ]}t dd  t d|d   t d  |j	| }t d|d   t d|d   t d|d   t d|d   t d|d   t d|d   t d|d    |d d!kp|d d!kp|d  d!k}|rt d" qt dd d t d# t d$ t d d d%}|
 D ]\}}|d }	|d }
t|d r,|d nd&}|d }t|r|d!kr|d7 }d'|
 dtt|d(d)| dt| d*d+}|| t d,| d-|	 d.t| d/ |d }t|r0|d!kr0|d7 }d'|
 dtt|d(d)| dt| d0d+}|| t d,| d-|	 d.t| d1 |d  }t|r|d!kr|d7 }d'|
 d tt|d(d)| dt| d2d+}|| t d,| d-|	 d.t| d3 qt dd  t d4 t d t d5t|  t d6t|ttd7d8 |D    t d9t|  t|d%kr t d: td;d< |D }td=d< |D }td>d< |D }|d%krt d?|  |d%krt d@|  |d%krt dA|  t dB t|dD ]8\}}t dC|dDdE|dF  dG|dH  dI|dJ   qnt dK t dL t d d |W S  ty } zht dd  t dM t d  t dNt|  t dO d%dPl}|  t d d |W  Y dP}~S dP}~0 0 dPS )Qu   
        Valida que las cantidades de motores, generadores y radiadores no excedan el máximo (1)
        mediante consulta SQL INDEPENDIENTE del Excel
        
        Returns:
            list: Lista de errores encontrados donde cantidad >= 2
        rO   u=   🔍 INICIANDO VALIDACIÓN DE CANTIDADES DE COMPONENTES (SQL)rP   u(   
📊 PASO 1: Ejecutando consulta SQL...u/   ⚠️  La consulta SQL no devolvió resultadosu   ✅ Consulta ejecutada: z registros obtenidosu$   
📋 Resumen de columnas obtenidas:z   Columnas: z   Tipos de datos:z      - rT   rX   u'   📊 PRIMERAS 5 FILAS DEL RESULTADO SQLrV   rY   u   📍 REGISTRO rB   z   OrderNum: OrderNumz   OrderLine: 	OrderLinez   OrderNum&Line: zOrderNum&Linez   JobNum2: JobNum2u      🔧 CantidadDeMotores: CantidadDeMotoresu      ⚡ CantidadDeGeneradores: CantidadDeGeneradoresu"      🌡️  CantidadDeRadiadores: CantidadDeRadiadoresrW   u)      ⚠️  ¡CANTIDAD EXCEDIDA DETECTADA!u$   🔎 PASO 2: Validando cantidades...u'      Criterio: Si cantidad >= 2 → ERRORr   z
Sin JobNumzOrderNum&Line: ZCANTIDAD_MAXIMAu   ⚠️ JobNum u*    motores detectados (máximo permitido: 1)rc   u   ❌ Error #z: OrderNum z - z motoresu.    generadores detectados (máximo permitido: 1)z generadoresu-    radiadores detectados (máximo permitido: 1)z radiadoresu2   📊 RESUMEN FINAL - VALIDACIÓN DE CANTIDADES SQLu      📋 Registros analizados: u      ✅ Registros sin errores: c                 S   s   g | ]}|d  qS )rd   r   r   r.   r   r   r   r   H  r   zEValidadorScore.validar_cantidades_componentes_sql.<locals>.<listcomp>u!      ❌ Total errores detectados: u%   
   📋 Detalle de errores por tipo:c                 s   s   | ]}|d  dkrdV  qdS )re   r   rB   Nr   r   r   r   r   	<genexpr>M  r   zDValidadorScore.validar_cantidades_componentes_sql.<locals>.<genexpr>c                 s   s   | ]}|d  dkrdV  qdS )re   r   rB   Nr   r   r   r   r   r   N  r   c                 s   s   | ]}|d  dkrdV  qdS )re   r   rB   Nr   r   r   r   r   r   O  r   u         • Motores excedidos: u!         • Generadores excedidos: u          • Radiadores excedidos: u   
   📋 Lista de errores:r]   rm   r   rd   rn   re   r_   rf   u-   
   ✅ NO SE DETECTARON CANTIDADES EXCEDIDASu=      🎉 Todas las órdenes tienen cantidades válidas (0 o 1)u3   ❌ ERROR CRÍTICO EN VALIDACIÓN DE CANTIDADES SQLro   rp   N)r*   r	   emptyr+   ru   r   r   r   r   r   Ziterrowsr   r   r-   intrx   r   r   rr   r,   rz   r{   )r   r   Zdf_cantidadesr   r   r~   r   Ztiene_errorr   Z	order_numZorder_line_fulljob_numZcantidad_motoresrh   Zcantidad_generadoresZcantidad_radiadoresZerrores_motoresZerrores_generadoresZerrores_radiadoresr   r.   rz   r   r   r   "validar_cantidades_componentes_sql  s    







 

 

$(


4
z1ValidadorScore.validar_cantidades_componentes_sqlc              
   C   sV  z|   sdddW S |  }|s.dddW S | |sDdddW S | |}|  \}}|sn| |g dW S |  \}}|  }|  }|| | | }	t	dt
|	  t	dt
|  t	d	t
|  t	d
t
|  | ||	|}
|
W S  tyP } zBt	dt|  ddl}|  ddt| dW  Y d}~S d}~0 0 dS )u   
        Ejecuta el flujo completo de validación
        INCLUYE detección de errores nativos de Excel
        
        Returns:
            dict: Reporte completo de la validación
        ERROR-   No se pudo cargar el catálogo de validaciónr   r   z-No se pudo descargar el archivo de SharePointz No se pudo leer el archivo ExcelNu    ✓ Total errores consolidados: z  - Errores Excel: z  - Filas eliminadas: z  - Errores de tipos: u   Error en validación completa: r   r   )r/   r?   r   r   r   r   r   r   r   r*   r+   r,   r-   rz   r{   )r   rL   Zerrores_excel_nativosZestructura_validar   r   Zerrores_filas_eliminadasr   Zerrores_cantidades_sqlZtodos_los_errores_datosr   r.   rz   r   r   r   ejecutar_validacion_completao  sV    

z+ValidadorScore.ejecutar_validacion_completaN)r   
__module____qualname____doc__r    r   r/   r?   r<   r   r   r   r   r   r   r   r   r   r   r   r   r   !   s    
"$ eZDC< 3r   c                 C   sv  z2t  }| du rD| s(ddddW S | } | sddddW S n>| sZddddW S ddl}|j| sdd	d
|  dW S | }|ddkrdd|dd|dW S |di dd}|dkrddd| d|di |||di dd|di ddddW S ddd| ||di dW S  typ } z"dddt	| dW  Y d}~S d}~0 0 dS )u  
    Función auxiliar para ser llamada desde ActualizarScore.py
    
    Esta función ejecuta la validación del Score y retorna un formato
    compatible con el módulo de actualización.
    
    Args:
        ruta_archivo (str, optional): Ruta del archivo Excel a validar.
                                      Si no se proporciona, descarga desde SharePoint.
    
    Returns:
        dict: {
            'success': bool,              # True si validación exitosa, False si hay errores
            'status': int,                # 200 si éxito, 400 si error
            'mensaje': str,               # Mensaje descriptivo
            'ruta_archivo': str,          # Ruta del archivo validado (si éxito)
            'reporte': dict,              # Reporte completo de validación (opcional)
            'errores': dict               # Errores encontrados (si falla)
        }
    
    Ejemplo de uso:
        from App.SupyCtrol_Module.IngenieroControl.ValidarScore import validar_score_para_actualizacion
        
        resultado = validar_score_para_actualizacion()
        if resultado['success']:
            ruta = resultado['ruta_archivo']
            # Continuar con el proceso...
        else:
            # Manejar errores...
    NFi  uH   No se pudo cargar el catálogo de validación desde CM_DataTypeValidator)successstatusr   z6No se pudo descargar el archivo Excel desde SharePointr   r   i  zEl archivo no existe: r   r   r   u   Error en validación)r   r   r   r   r   r   zSe encontraron u    errores de validaciónr   r   r   )r   r   r   )r   r   r   r   r   ZdetallesTr2   u%   Validación exitosa. Datos correctos.)r   r   r   rL   r   r     u   Error crítico en validación: )
r   r/   r?   r#   r$   existsr   r7   r,   r-   )rL   	validadorr#   r   r   r.   r   r   r    validar_score_para_actualizacion  sp    





	r   c                 C   s4   | j ddgddd }| j ddgddd	 }d
S )u   
    Registra la ruta de ejecución de validación en Flask
    
    Args:
        app: Instancia de Flask
        mail: Instancia de Flask-Mail
    z0/SyC/IngenieroControl/ModuloValidacionScore/testGET)methodsc                   S   s   t ddt ddS )z5Ruta de prueba para verificar que el backend funcionaTu$   ¡Backend funcionando correctamente!r   )r   r   r   )r   r   r   r   r   r   r   r   test_validacion;  s
    z2ejecutar_validacion_score.<locals>.test_validacionz4/SyC/IngenieroControl/ModuloValidacionScore/ejecutarPOSTc               
   S   s`   z t d t } |  }t|W S  tyZ } z"tdt|ddfW  Y d}~S d}~0 0 dS )u/   Ejecuta la validación del Score y retorna JSONu"   Iniciando validación del Score...r   r   r   N)r*   r   r   r   r,   r-   )r   r   r.   r   r   r   ejecutar_validacionD  s    
z6ejecutar_validacion_score.<locals>.ejecutar_validacionN)route)appmailr   r   r   r   r   ejecutar_validacion_score1  s    

r   )N)r#   r6   Zpandasr   ior   r   flaskr   configr   r   Z4Consultas_SQL.SupYCtrol.IngDeControl.ValidarScoreSQLr   r   r	   Z9App.SupyCtrol_Module.IngenieroControl.ValidarScoreHelpersr
   r   getenvr   Configr   r   r   Z
set_optionr   r   r   r   r   r   r   <module>   s6          !
v