+
    :mai                     z   ^ RI t ^ RIt^ RIt^ RIHt ^ RIHt ^ RIHt ^ RI	H
t
Ht ^ RIHtHtHt ^ RIHtHt ] P&                  ! RR	4      t]R
8X  d   ]M]
tRtRtRt]P2                  ! RR4       ]P2                  ! RR4       ]P2                  ! RR4       ]P2                  ! R^24        ! R R4      tRR ltR tR# )    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=EStyzV5jqTRGqhyxo4jfzmIBYCfPhbrU4xMICcpWqMSqiwCM_Scorezdisplay.max_columnszdisplay.max_rowszdisplay.widthzdisplay.max_colwidthc                   r   a  ] tR t^!t o RtR tR tR tR tR t	R t
R tR	 tR
 tR tR tR tR tRtV tR# )ValidadorScoreu7   
Clase principal para manejar la validación del Score
c                    \         V n        \        V n        \        V n        V P                  4       V n        R V n        R V n	        . V n
        \        P                  ! 4       P                  R4      V n        R # )Nz%Y%m%d_%H%M%S)url_sharepoint_globalurl_sharepointnombre_hoja_globalnombre_hojanombre_tabla_excel_globalnombre_tabla_excel_obtener_ruta_descargaruta_descargacatalogo_validaciondf_scoreerrores_validacionr   nowstrftime	timestamp)selfs   &`c:\Users\victor.cervantes\Desktop\Elep\src\App\SupyCtrol_Module\IngenieroControl\ValidarScore.py__init__ValidadorScore.__init__&   sZ    3-";!88:#' "$!00A    c                    \         R8X  d   RpM4\        P                  P                  \        P                  ! 4       RR4      p\        P
                  ! VRR7       V# )ul   
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tempscore_validacionesT)exist_ok)r   ospathjoingetcwdmakedirs)r"   rutas   & r#   r   %ValidadorScore._obtener_ruta_descarga0   sE     $>D 77<<		V5IJD 	D4(r&   c                    \        4       V n        V P                  '       g   \        R4       R# \        R\        V P                  4       R24       R#   \         d#   p\        R\        T4       24        Rp?R# Rp?ii ; i)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"   es   & r#   inicializar_catalogo#ValidadorScore.inicializar_catalogoC   ss    	'B'DD$+++MN6s4;S;S7T6UU^_` 	4SVH=>	s   ,A "A BA<<Bc                t    \        R4       \        P                  ! V P                  ^R7      pVP                  ^8w  d   \        RVP                   24       R# RV P
                   R2p\        P                  P                  V P                  V4      p\        VR4      ;_uu_ 4       pVP                  VP                  4       RRR4       \        RV 24       \        R	8X  d   V P                  4        V#   + '       g   i     L;; i  \         d#   p\        R
\!        T4       24        Rp?R# Rp?ii ; i)zs
2. Descarga el archivo Excel desde SharePoint

Returns:
    str: Ruta del archivo descargado o None si hubo error
z'Descargando archivo desde SharePoint...)timeoutu   Error al descargar: código NScore_.xlsxwbzArchivo descargado: r   zError al descargar Excel: )r4   requestsgetr   status_coder!   r+   r,   r-   r   openwritecontentr   _limpiar_archivos_antiguosr6   r7   )r"   responsenombre_archivoruta_completafr8   s   &     r#   descargar_excelValidadorScore.descargar_excelX   s   	;<||D$7$7DH##s*4X5I5I4JKL  &dnn%5U;NGGLL););^LMmT**a(() + (89 L(//1   +*  	.s1vh78	s7   AD
 AD
 (C72D
 7D	D
 
D7D22D7c                    \         P                  ! 4       pVP                  pVP                  pV^8:  d   ^^V,
          ,
          pV^,
          pMV^,
          pTpV VR 2p\        P
                  ! V P                  4      pV F  pVP                  R4      '       g   K  VP                  R4      '       g   K5   VP                  R4      ^,          R,          p	W8  dQ   \        P                  P                  V P                  V4      p
\        P                  ! V
4       \        RV 24       K  K  	  R#     K  ; i  \         d#   p\        R\        T4       24        Rp?R# Rp?ii ; i)	z+
2.4 Elimina archivos anteriores a 3 meses
02dr=   r>   _:N   NzArchivo antiguo eliminado: z$Error al limpiar archivos antiguos: N)r   r   monthyearr+   listdirr   
startswithendswithsplitr,   r-   remover4   r6   r7   )r"   fecha_limite
mes_actual   año_actual
mes_limite   año_limitefecha_limite_strarchivosarchivofecha_archivoruta_archivor8   s   &           r#   rF   )ValidadorScore._limpiar_archivos_antiguosz   s6   	C#<<>L%++J&++KQ1z>2
)Ao'!^
)"-z#.>?zz$"4"45H#%%h//G4D4DW4M4M!(/c(:1(=b(A(;+-77<<8J8JG+TLIIl3!$?y"IJ < $!  	C8QABB	Cs7   BD=  D= :A3D5-D= 5D:7D= =E*E%%E*c                *   ^ RI Hp ^ RIHp . p \	        Rm4       \	        R4       \	        Rl4       \	        R4       \	        RV 24       \	        R4       V! VRR	7      p\	        R
4       \	        RVP
                   24       \	        RV P                   R24       V P                  VP
                  9  dD   \	        RV P                   R24       \	        RVP
                   24       VP                  4        V# WPP                  ,          p\	        R4       \	        RVP                   24       \	        RVP                   24       \	        RVP                   24       \	        R4       / p\        V^,          ^R7       F>  w  rV	P                  '       g   K  \        V	P                  4      P                  4       Wx&   K@  	  \	        R\        V4       R24       \	        R4       \!        VP#                  4       4      R,           F  w  r\	        RV
R RV 24       K  	  \        V4      ^
8  d    \	        R\        V4      ^
,
           R24       \	        R 4       \	        R!4       \	        Rl4       ^ p^ p^p\        VP%                  ^R"7      ^R7       EF  w  ppV^,          pW8:  Eda   \	        RRn 24       \	        R#V R$V 24       \	        Rn 4       ^ p^ p^ p\	        R%4       \        VR&,          ^R7       F  w  rVP'                  VR'V 24      pV	P                  pV	P(                  pV	P*                  pVe   VR)8X  d   R*pV^,          pM\        V4      R+,          pV^,          pVV8H  pV'       d   V^,          pR,pMR-p\	        R.V R/V R0VR1 R2VR3 R4V R524       K  	  \        V4      p\	        R6V R724       \	        R8V 24       \	        R9V 24       \	        R:V 24       \	        R;V 24       V^ 8  d   \	        R<4       \        V^R7       F  w  rV	P(                  V8X  g   K  V^,          pVP'                  VR=V 24      pV	P                  '       d   \        V	P                  4      MR>pV	P*                  pVP-                  R?VR@VRAVRBRCRDREV 2/4       W8:  dJ   \	        RFV RG24       \	        RHV 24       \	        RIV 24       \	        RJV 24       \	        RKV 24       K  \	        RLV RMV RNV ROV RPV 2
4       K  	  W8  g   EK  V^d,          ^ 8X  g   EK  \	        RQV RRV RS24       EK  	  \	        RRl 24       \	        RT4       VP                  4        \	        RU4       \	        RRl 24       \	        RV4       \	        Rl 4       \	        RWVP/                  RX4      Ro,           24       \	        RYV P                   24       \	        RZV 24       \	        R[\        V4       24       \	        R\V\        V4      ,          R] 24       V^ 8  d   \	        R^V 24       \	        R_4       / pV F(  pVRA,          pVP'                  V^ 4      ^,           VV&   K*  	  \1        VP#                  4       4       F  w  pp \	        R`V RV  Ra24       K  	  \	        Rb4       \        V^4       F5  w  p!p\	        R.V!Rc RdVR?,          Re RfVR@,          R1 RfVRA,           24       K7  	  M\	        Rg4       \	        Rh4       \	        Rl R24       V#   \2         dv   p"\	        RRl 24       \	        Ri4       \	        Rl 4       \	        Rj\        T"4       24       \	        Rk4       ^ R(Ip#T#P7                  4        \	        Rl R24       Tu R(p"?"# R(p"?"ii ; i)pu  
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
)load_workbook)
TYPE_ERROR
uB   🔍 INICIANDO DETECCIÓN DE ERRORES NATIVOS DE EXCEL CON OPENPYXLu!   
📂 PASO 1: Abriendo archivo...z	   Ruta: u?      Modo: data_only=False (mantiene fórmulas y detecta errores)T)	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)...)startu      ✅ z columnas detectadasz
   Primeras 10 columnas::N{   Nz
      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)min_rowu
   📍 FILA u    (Fila Excel) - Índice z"   Mostrando primeras 10 columnas::N#   NCol_N    [VACÍO]N2   Nu	   ❌ 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!Columna_z#ERROR!filacolumnavalortipo_esperadoERROR_EXCELerroru&   🚫 Error nativo de Excel detectado: u   
      🚨 ERROR #z ENCONTRADO:z         Celda: z         Fila Excel: z         Columna: z         Valor: u      ❌ Error #z: Fila z, Columna 'z' [z]: 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:u
         • z ocurrencia(s)u#   
   📋 Lista completa de errores:3dz. Fila 4d | 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:d====================================================================================================e
====================================================================================================,  ────────────────────────────────────────────────────────────────────────────────────────────────────)openpyxlrd   openpyxl.cell.cellre   r4   
sheetnamesr   close
dimensionsmax_row
max_column	enumeratevaluer7   stripr5   listitems	iter_rowsrA   	data_type
coordinateappendrV   sortedr6   	traceback	print_exc)$r"   ra   rd   re   errores_excelr?   wscolumnascol_idxcellidxnombrecontador_erroresfilas_procesadasMOSTRAR_PRIMERAS_N_FILASrow_idxrowceldas_con_valorceldas_vaciasceldas_con_errornombre_columnar|   	tipo_dato
coordenadavalor_mostrares_errormarcadortotal_celdas_filavalor_errortipos_errorr   tipocantidadir8   r   s$   &&                                  r#   _detectar_errores_excel_nativos.ValidadorScore._detectar_errores_excel_nativos   s    	+1O	!.!VW'N
 68Il^,-SU|t<B8:/?@
 78H8H7INOr}}4,T-=-=,>oNO.r}}o>?
$$$$%B:<)"--9:,RZZL9:/?@
 JLH!*2a5!::::(+DJJ(=(=(?H% "; GCM?*>?@.0#HNN$45d;;
3r("VH56  < 8}r!S]R%7$8GH
 SUMO'N  '($ )",,q,*A K K A% 
 $?Byk*+Jwi/GHXGYZ[YK)'($$%M'($ >@)23s81)E)1ggY?O)P !%

$(NN	%)__
 !=ERK,6M)Q.M,/JsOM,1, $-
#:#,1,'2H',H xj:,bPS@TTWXefiWjjrs|r}}~  A3 *F8 ),C%3G9A>?45F4GHI12B1CDE/?@12B1CDE'!+ LN
 &/s!%<MG~~3(A-()1g'?S)T9=c$**o%)__
 &,,"G%~#[+]#'Mk]%[.  ,G!$89I8J,"WX!$4ZL"AB!$9'"CD!$6~6F"GH!$4[M"BC "N3C2DGG9T_`n_oors}r~  B  CN  BO  #P  Q7 &=< $>CSVYCY]^C^./?.@IYHZZrstu !L~ Bwi.!IKHHJ9;
 Bwi.!OQWI%l&8&8&=b&A%BCDN4#3#3"456./?.@AB1#h-AB45EH5UVW4XYZ!#9:J9KLM<> !*E >D(3a(@1(DK% + '-[->->-@&AND(JtfBxjGH 'B <> )- ;HAuF1R&fb/AU9EUVYDZZ]^cdk^l]mno !< JLVXWIR.!   		!Bwi.!HJWIJs1vh'(.0!WIR.!  		!sN   C(\ 9B\ G\ 6B3\ ./\ B1\ \ &G+\ ^A*^^^c                ,    \        R4       \        P                  ! V4      pV P                  VP                  9  d4   \        RV P                   R24       \        RVP                   24       R# \        P
                  ! WP                  \        R7      V n        V P                  P                   Uu. uF  q3P                  4       NK  	  upV P                  n        \        R\        V P                  4       R\        V P                  P                  4       R	24       \        R"4       \        R4       \        R!4       \        ^\        V P                  4      4      p\        V4       EF  pV^,           p\        R
R! 24       \        RV RV R24       \        R! 4       V P                  P                  V.,          P                  pR.Vn        V P                  P                  V,          P                  4        Fl  w  r\        P                   ! V	4      '       d   Rp
MV	R8X  d   Rp
M\        V	4      R,          p
\#        V	4      P$                  p\        RVR RV
R RV R24       Kn  	  EK  	  \        R"4       \        R4       \        R!4       \        R4       \        V P                  P&                  P)                  4       4       \        R4       V P                  P+                  4       P-                  4       pW^ 8  ,          p\        V4      ^ 8  d   \        VP)                  4       4       M\        R4       \        R#4       R# u upi   \.         d7   p\        R\        T4       24       ^ R IpTP3                  4         R p?R# R p?ii ; i)$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)
sheet_namedtypeu   Archivo leído correctamente: z filas, r3   rf   u#   📊 PRIMERAS 5 FILAS DEL DATAFRAMEu   FILA NÚMERO u    (índice DataFrame: rw   Valorz[NULL]ro   rp   :Nd   N  z<45ru   z<55rt   ]zFIN DE PRIMERAS 5 FILASu    
📋 RESUMEN DE TIPOS DE DATOS:u"   
⚠️  RESUMEN DE VALORES NULOS:u   ✓ No hay valores nulosTzError al leer Excel: Nz======================================================================================================================================================z
======================================================================================================================================================z
======================================================================================================================================================
)r4   pd	ExcelFiler   sheet_names
read_excelr7   r   columnsr   r5   minrangeilocTr   isnatype__name__dtypes	to_stringisnullsumr6   r   r   )r"   ra   
excel_filecolnum_filas_mostrarr   
fila_excelfila_dfcolumna_nombrer|   valor_formateador   nulosnulos_con_datosr8   r   s   &&              r#   
leer_excelValidadorScore.leer_excel  s   N	,-l3Jz'='==()9)9(::STU+J,B,B+CDE MM,CSCS[^_DM =AMM<Q<Q$R<QSYY[<Q$RDMM!23t}}3E2FhsSWS`S`ShShOiNjjstu .!78'N !$As4=='9 :./ 1W
7)n%j\1Fse1MN	# --,,cU355#*) .2]]-?-?-D-J-J-L)Nwwu~~+3("+5(+.u:d+;(  ;//DB~c2#6Fs5K2dVSTUV .M 04 .!+,'N 56$--&&0023 78MM((*..0E#AI.O?#a'o//1201'(s %Sv  	)#a&23!		s2   A-M 1AM 4MI?M M N+NNc           
        . p V P                   P                  P                  4       p\        V P                  P                  4       4      p\        V4      \        V4      ,          p\        V4      ^ 8X  d   VP                  RRRR/4       RV3# \        \        V4      \        V4      ,
          4      p\        \        V4      \        V4      ,
          4      p\        R4       \        R4       \        R4       \        R\        V4       24       \        R4       \        R4       \        \        V4      ^4       F  w  rx\        R	VR
 RV 24       K  	  V'       dU   \        R\        V4       24       \        R4       \        R4       \        V^4       F  w  rx\        R	VR
 RV 24       K  	  V'       du   \        R\        V4       24       \        R4       \        R4       \        V^4       F7  w  rxV P                  P                  VR4      p	\        R	V RVR RV	 R24       K9  	  \        R4       \        R4       \        R4       R. 3#   \         d0   p
TP                  RRRR\        T
4       2/4       RT3u Rp
?
# Rp
?
ii ; i)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   
ESTRUCTURAmensajeu^   No hay columnas en común entre el Excel y el catálogo (Origin=Manual). Verifica los nombres.Fu   ANÁLISIS DE COLUMNASu:   
✓ Columnas con Origin='Manual' en común para validar: u'   
Listado de columnas que se validarán:r   rj   . 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/Arv   z (rw   u%   ✓ Validación de estructura exitosaTzError al validar estructura: NzP================================================================================zQ
================================================================================zP--------------------------------------------------------------------------------zQ================================================================================
)r   r   tolistr   r   keyssetr5   r   r   r4   r   rA   r6   r7   )r"   errorescolumnas_excelcolumnas_catalogocolumnas_comunescolumnas_solo_excelcolumnas_solo_catalogor   r   r   r8   s   &          r#   validar_estructura!ValidadorScore.validar_estructura  sr    7	"!]]2299;N $T%=%=%B%B%D E  #>2S9J5KK#$)L   g~% #)^)<sCT?U)U"V%+C0A,BSEX,X%Y" - )*&MOPSTdPeOfgh<=(O#F+;$<a@1R&3%() A #WX[\oXpWqrsIJh'(;Q?FABqfBse,- @ &WX[\rXsWtuvLMh'(>BFA3377UCDBqcC9BtfA67 C - 9:- 8O 	"NN:3q6(C  '>!	"s3   B
I CI AI 9BI J$JJJc                <    \        V P                  4      p\        V P                  4      w  V n        p\        V P                  4      pW,
          p\        RV R24       RVRVRV/pWR3#   \         d&   p\        R\        T4       24       R. 3u Rp?# Rp?ii ; i)ut   
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)r5   r   r   r4   r6   r7   )r"   r   filas_eliminadas_detaller   r   estadisticasr8   s   &      r#   aplicar_tratamiento_datos(ValidadorScore.aplicar_tratamiento_datos   s    	"4==1 7H6V3DM3.M/?./?.@@QRS #$4"$4L  99 	23q6(;<8O	s   A(A+ +B6BBBc                   . p \        R4       \        V P                  P                  P	                  4       4      p\        V P
                  P                  4       4      pW#,          p\        R\        V4       24       \        P                   Uu. uF  pWT9   g   K  VNK  	  ppV'       d   \        RV 24       V F  pV P
                  V,          p\        V P                  V,          4       Fz  w  r\        P                  ! V
VVR7      w  rV'       d   K*  TP                  RV	^,           RTR\        P                  ! V
4      '       d   \        V
4      R,          MR	R
VRV/4       K|  	  K  	  \        R\        V4       R24       V# u upi   \          d;   p\        R\        T4       24       R^ RRRRR
RRR\        T4       2/.u Rp?# Rp?ii ; i)u  
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): u*   ⚠️  Columnas obligatorias (NOT NULL): )r   rz   r{   r|   rq   rp   r}   r   u   ✓ Validación completada: z errores encontradosz!Error al validar tipos de datos: SISTEMAro      Error crítico: N)r4   r   r   r   r   r   r   r5   r   COLUMNAS_OBLIGATORIASr   validar_por_tipo_sqlr   r   notnar7   r6   )r"   r   r   r   columnas_a_validarr   #columnas_obligatorias_en_validacionr{   tipo_sqlr   r|   	es_validomensaje_errorr8   s   &             r#   validar_tipos_datos"ValidadorScore.validar_tipos_datos>  s    4	/0 !6!6!=!=!?@N #D$<$<$A$A$C D "0!CMcRdNeMfgh  3HH3H, H 0 3 3BCfBghi-33G< #,DMM',B"CJC/B/W/W '.0,I %9"C!G%w#SZ_Z+X#](  #D	 .* 0W>RSTN=3@  	5c!fX>?9+CF84  	sC   BF FF#A1F 2F >F F G/G
GGc                Z    \        V4      \        V4      ,           p\        V P                  P                  P	                  4       4      p\        V P
                  P                  4       4      pWV,          p/ pV F0  p	V	P                  RR4      p
VP                  V
^ 4      ^,           W&   K2  	  V F0  p	V	P                  RR4      p
VP                  V
^ 4      ^,           W&   K2  	  RV P                  R\        P                  ! 4       P                  R4      RV^ 8X  d   R	MR
RRV'       d   VP                  R^ 4      M^ RV'       d   VP                  R^ 4      M^ RV'       d   VP                  R^ 4      M^ R\        V4      R\        V4      R\        V4      RVR\        V4      R\        V4      /	RVRRVRV//p\        V'       d   VP                  R^ 4      M^ VV\        P                  ! 4       VR,          R7       V#   \         d#   p\        R\        T4       24        Rp?R# Rp?ii ; i)u5   
5.3 Genera el reporte consolidado de la validación
r   r   r}   	TIPO_DATOr!   fecha_validacion%Y-%m-%d %H:%M:%SestadoEXITOSOCON_ERRORESr   r   r   r   r   r   columnas_catalogo_manualcolumnas_validadastotal_erroreserrores_estructuraerrores_datoserrores_por_tipor   
estructuradatos)total_filasr
  r  r!   r  zError al generar reporte: N)r5   r   r   r   r   r   r   rA   r!   r   r   r    r	   r6   r4   r7   )r"   r  r  stats_tratamientor
  r   r   r	  r  r   r   reporter8   s   &&&&         r#   generar_reporte_consolidado*ValidadorScore.generar_reporte_consolidado  s   4	 23c-6HHM !!6!6!=!=!?@N #D$<$<$A$A$C D!/!C!+yy6)9)=)=dA)F)J & , 'yy+>)9)=)=dA)F)J & '
 T^^"HLLN$;$;<O$P}'9)}&Xi(9(=(=>PRS(Top&Uf(9(=(=oq(Qlm&Xi(9(=(=>PRS(Top$c.&9.4E0F(#.@*A#](#.@*A#S%7
! #$4 "4]!G, #IZ-11/1E`a+!1",,.x( N 	.s1vh78	s+   D%G= (G= G=  BG= =H*H%%H*c                   . p \        RI4       \        R4       \        RH4       \        R4       \        4       pVP                  '       d   \        R4       V# \        R\        V4       R24       \        R4       \        R\	        VP
                  4       24       \        R	4       VP
                   F$  p\        R
V RW#,          P                   24       K&  	  \        RRH 24       \        R4       \        RH4       \        ^\        V4      4      p\        V4       EF#  p\        RRJ 24       \        RV^,            24       \        RJ 4       VP                  V,          p\        RVR,           24       \        RVR,           24       \        RVR,           24       \        RVR,           24       \        RVR,           24       \        RVR,           24       \        RVR,           24       VR,          ^8  ;'       g!    VR,          ^8  ;'       g    VR,          ^8  pV'       g   EK  \        R4       EK&  	  \        RRH R24       \        R4       \        R4       \        RH R24       ^ pVP                  4        EF  w  rVVR,          p	VR,          p
\        P                  ! VR,          4      '       d
   VR,          MRpVR,          p\        P                  ! V4      '       dq   V^8  dj   V^,          pR R!V
 2R"RR#\        \        V4      4      R$R%R&R'V R\        V4       R(2/pVP                  V4       \        R)V R*V	 R+\        V4       R,24       VR,          p\        P                  ! V4      '       dq   V^8  dj   V^,          pR R!V
 2R"RR#\        \        V4      4      R$R%R&R'V R\        V4       R-2/pVP                  V4       \        R)V R*V	 R+\        V4       R.24       VR,          p\        P                  ! V4      '       g   EK  V^8  g   EK  V^,          pR R!V
 2R"RR#\        \        V4      4      R$R%R&R'V R\        V4       R/2/pVP                  V4       \        R)V R*V	 R+\        V4       R024       EK  	  \        RRH 24       \        R14       \        RH4       \        R2\        V4       24       \        R3\        V4      \        \!        V Uu. uF  pVR ,          NK  	  up4      4      ,
           24       \        R4\        V4       24       \        V4      ^ 8  d   \        R54       \#        R6 V 4       4      p\#        R7 V 4       4      p\#        R8 V 4       4      pV^ 8  d   \        R9V 24       V^ 8  d   \        R:V 24       V^ 8  d   \        R;V 24       \        R<4       \%        V^4       F3  w  pp\        R=VR> R?VR ,           R@VR",           RAVR#,           24       K5  	  M\        RB4       \        RC4       \        RH R24       V# u upi   \&         dv   p\        RRH 24       \        RD4       \        RH 4       \        RE\        T4       24       \        RF4       ^ RGIpTP+                  4        \        RH R24       Tu RGp?# RGp?ii ; i)Ku   
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
rf   u=   🔍 INICIANDO VALIDACIÓN DE CANTIDADES DE COMPONENTES (SQL)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      - rk   u'   📊 PRIMERAS 5 FILAS DEL RESULTADO SQLu   📍 REGISTRO z   OrderNum: OrderNumz   OrderLine: 	OrderLinez   OrderNum&Line: zOrderNum&Linez   JobNum2: JobNum2u      🔧 CantidadDeMotores: CantidadDeMotoresu      ⚡ CantidadDeGeneradores: CantidadDeGeneradoresu"      🌡️  CantidadDeRadiadores: CantidadDeRadiadoresu)      ⚠️  ¡CANTIDAD EXCEDIDA DETECTADA!u$   🔎 PASO 2: Validando cantidades...u'      Criterio: Si cantidad >= 2 → ERRORz
Sin JobNumrz   zOrderNum&Line: r{   r|   r}   CANTIDAD_MAXIMAr   u   ⚠️ JobNum u*    motores detectados (máximo permitido: 1)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: u!      ❌ Total errores detectados: u%   
   📋 Detalle de errores por tipo:c              3   D   "   T F  qR ,          R8X  g   K  ^x  K  	  R# 5i)r{   r  N .0r8   s   & r#   	<genexpr>DValidadorScore.validar_cantidades_componentes_sql.<locals>.<genexpr>M  s     %`AiLL_<_aa    
 c              3   D   "   T F  qR ,          R8X  g   K  ^x  K  	  R# 5i)r{   r  Nr  r  s   & r#   r!  r"  N  s     )hW)Pg@g!!Wr#  c              3   D   "   T F  qR ,          R8X  g   K  ^x  K  	  R# 5i)r{   r  Nr  r  s   & r#   r!  r"  O  s     (fGq|Oe?eGr#  u         • Motores excedidos: u!         • Generadores excedidos: u          • Radiadores excedidos: u   
   📋 Lista de errores:rs   r   r   r   ru   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 SQLr   r   Nr   r   r   )r4   r
   emptyr5   r   r   r   r   r   r   iterrowsr   r   r7   intr   r   r   r   r6   r   r   )r"   r   df_cantidadesr   r   r   r   tiene_errorr   	order_numorder_line_fulljob_numcantidad_motoresr   cantidad_generadorescantidad_radiadoresr8   errores_motoreserrores_generadoreserrores_radiadoresr   r   s   &                     r#   "validar_cantidades_componentes_sql1ValidadorScore.validar_cantidades_componentes_sql  s    e	.!QR'N
 =>:<M"""GH,S-?,@@TUV 9;M$}'<'<"=!>?@&($,,R(:(@(@'ABC - Bwi.!;<'N #As='9 :./9+&'sQwi01%#((-c*o%678s;'7&89:*3+?*@ABS^$4563C8K4L3MNO6s;R7S6TUV:3?U;V:WXY +,1 5 5/0A55 5./14  ;EG/ 02 Bwir"#
 89;=WIR.! )224
O	"%o"6,.HHS^,D,D#i.,
 $'':#; 88,--2Ba2G$)$//1B C!#6S)9%:!;'):>'"SAQ=R<SS}!~E NN5)K(8'9YKsSVWgShRiiqrs
 (++B'C$880116Ja6O$)$//1B C!#:S)=%>!?'):>'"SAU=V<W  XF  "GE NN5)K(8'9YKsSVWkSlRmmyz{
 '**@&A#88/005HA5M$)$//1B C!#9S)<%=!>'):>'"SAT=U<V  WD  "EE NN5)K(8'9YKsSVWjSkRllwxyg 5p Bwi.!FG'N23}3E2FGH23}3ECdkPldk_`QRSYQZQZdkPlLmHn3n2opq5c'l^DE7|a>@"%%`%`"`&))hW)h&h#%((fG(f%f""Q&9/9JKL&*=>Q=RST%)<=O<PQR35 )'1 5HAuF1R&5=/U9=M<NcRWX_R`Qabc !6 FHUWWIR.!N3 Qm6  		Bwi.!GIWIJs1vh'(.0!WIR.!N		sa   AY  GY   Y  8B?Y  8BY  BY  %Y  /CY  6X;D2Y  ;Y   [ A*Z;5[ ;[ c                J    V P                  4       '       g   RRRR/# V P                  4       pV'       g   RRRR/# V P                  V4      '       g   RRRR/# V P                  V4      pV P	                  4       w  r4V'       g   V P                  V. R4      # V P                  4       w  rVV P                  4       pV P                  4       pW&,           V,           V,           p	\        R\        V	4       24       \        R	\        V4       24       \        R
\        V4       24       \        R\        V4       24       V P                  VV	V4      p
V
#   \         dH   p\        R\        T4       24       ^ RIpTP                  4        RRRR\        T4       2/u Rp?# Rp?ii ; i)u   
Ejecuta el flujo completo de validación
INCLUYE detección de errores nativos de Excel

Returns:
    dict: Reporte completo de la validación
r  ERRORr   -   No se pudo cargar el catálogo de validaciónz-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   )r9   rK   r   r   r   r  r   r   r4  r4   r5   r6   r7   r   r   )r"   ra   errores_excel_nativosestructura_validar  r  errores_filas_eliminadasr  errores_cantidades_sqltodos_los_errores_datosr  r8   r   s   &            r#   ejecutar_validacion_completa+ValidadorScore.ejecutar_validacion_completao  s   <	,,..gN 
  //1LgN 
 ??<00gA  %)$H$H$V!484K4K4M1$77&  ;?:X:X:Z7 446M%)%L%L%N" '<&VYf&fi&#4S9P5Q4RST',A(B'CDE*3/G+H*IJK*3}+=*>?@66"'!G N 	3CF8<=!'-c!fX6 		sD   E E E E E E =E B8E F"<FF"F")r   r   r   r   r   r   r!   r   N)r   
__module____qualname____firstlineno____doc__r$   r   r9   rK   rF   r   r   r   r   r   r  r4  r>  __static_attributes____classdictcell__)__classdict__s   @r#   r   r   !   sa     B&* D!CH`!HXtB"H<AF8xodD Dr&   r   c                p    \        4       pV f@   VP                  4       '       g	   RRRRRR/# VP                  4       p V '       g	   RRRRRR/# MNVP                  4       '       g	   RRRRRR	/# ^ RIpVP                  P                  V 4      '       g   RRRR
RRV  2/# VP                  4       pVP                  R4      R8X  d   RRRRRVP                  RR4      RV/# VP                  R/ 4      P                  R^ 4      pV^ 8  di   RRRRRRV R2RVP                  R/ 4      RVRRVRVP                  R/ 4      P                  R^ 4      RVP                  R/ 4      P                  R^ 4      //# RRR^RRRV RVRVP                  R/ 4      /#   \         d   pRRRRRR\        T4       2/u Rp?# Rp?ii ; i)uk  
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...
NsuccessFstatusi  r   uH   No se pudo cargar el catálogo de validación desde CM_DataTypeValidatorz6No se pudo descargar el archivo Excel desde SharePointr8  i  zEl archivo no existe: r  r7  u   Error en validaciónr  r   r
  zSe encontraron u    errores de validaciónr   detallesr  r  Tu%   Validación exitosa. Datos correctos.ra     u   Error crítico en validación: )
r   r9   rK   r+   r,   existsr>  rA   r6   r7   )ra   	validadorr+   r  r
  r8   s   &     r#    validar_score_para_actualizacionrN    s:   >T
"$	 1133uci  %446LucW    1133ucN  77>>,//uc!7~F  88: ;;x G+5#7;;y2HI7	   NB7;;OQO15#_]O;RS7;;y"57#]('++nb*I*M*MNbde*f#W[[%D%H%HZ[%\  tc>LwGKK;
 	
  
uc8QA
 	

sX   #F F F F F %F -$F 
F ?F BF .F F5F0*F50F5c                n    V P                  RR.R7      R 4       pV P                  RR.R7      R 4       pR# )	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            
     h    \        RRRRR\        P                  ! 4       P                  R4      /4      # )z5Ruta de prueba para verificar que el backend funcionarH  Tr   u$   ¡Backend funcionando correctamente!r!   r  )r   r   r   r    r  r&   r#   test_validacion2ejecutar_validacion_score.<locals>.test_validacion;  s8     t=001DE
  	r&   z4/SyC/IngenieroControl/ModuloValidacionScore/ejecutarPOSTc            	          \        R4       \        4       p V P                  4       p\        V4      #   \         d%   p\        RRR\        T4      /4      R3u Rp?# Rp?ii ; i)u/   Ejecuta la validación del Score y retorna JSONu"   Iniciando validación del Score...r  r7  r   rK  N)r4   r   r>  r   r6   r7   )rM  r  r8   s      r#   ejecutar_validacion6ejecutar_validacion_score.<locals>.ejecutar_validacionD  sk    		67&(I<<>G7## 	'3q6   	s   /2 A!AA!A!N)route)appmailrS  rW  s   &&  r#   ejecutar_validacion_scorer\  1  sM     	YYAE7YS T 	YYEPVxYX Yr&   )N)r+   r@   pandasr   ior   r   flaskr   configr   r   4Consultas_SQL.SupYCtrol.IngDeControl.ValidarScoreSQLr   r	   r
   9App.SupyCtrol_Module.IngenieroControl.ValidarScoreHelpersr   r   getenvr   Configr   r   r   
set_optionr   rN  r\  r  r&   r#   <module>rf     s    
      6 W  W l IIk=1	&,6	<M l  &  #T *  $ ' ot $ $b )R Rts
lr&   