
    sz0i*.                     V    S r SSKrSSKrSSKrSSKJr  SSKJrJ	r	   " S S5      r
S rg)u:   
Funciones auxiliares para validación de datos del Score
    N)datetime)DecimalInvalidOperationc                       \ rS rSrSrS/r\S 5       r\S 5       r\S 5       r	\S 5       r
\S 5       r\S	 5       r\S
 5       r\SS j5       rSrg)ValidadorTiposDatos   uB   
Clase para validar tipos de datos según el catálogo SQL Server
OrderNum&Linec                    U R                  5       R                  5       n SnSn[        R                  " X 5      nU(       aE  UR	                  S5      S[        UR	                  S5      5      [        UR	                  S5      5      4$ [        R                  " X5      nU(       a-  UR	                  S5      [        UR	                  S5      5      SS4$ U SSS4$ )u   
Extrae información del tipo de dato SQL Server

Args:
    tipo_sql (str): Tipo SQL como 'NVARCHAR(50)', 'DECIMAL(18,2)', 'INT'
    
Returns:
    tuple: (tipo_base, longitud, precision, escala)
z(\w+)\((\d+)\)z(\w+)\((\d+),(\d+)\)   N      )upperstriprematchgroupint)tipo_sqlpatron_con_longitudpatron_decimalr   s       xC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\App\SupyCtrol_Module\IngenieroControl\ValidarScoreHelpers.pyextraer_info_tipo_sql)ValidadorTiposDatos.extraer_info_tipo_sql   s     >>#))+ 00 2;;q>4U[[^)<c%++a.>QQQ ,7;;q>3u{{1~#6dBB tT))    c                     [         R                  " U 5      (       d  U S:X  a  g [        [        U 5      5      nSUs=::  a  S::  a   g  SSU  34$ ! [        [
        4 a
    SSU  34s $ f = f)u!   Valida si el valor es INT válido TNi   iFzValor fuera de rango INT: !   No es un número entero válido: pdisnar   float
ValueError	TypeErrorvalorval_ints     r   validar_intValidadorTiposDatos.validar_int<   s     775>>Ub[	F%,'Gg33! 4  :5'BBBI& 	F=eWEEE	F   "A A A)(A)c                     [         R                  " U 5      (       d  U S:X  a  g [        [        U 5      5      nSUs=::  a  S::  a   g  SSU  34$ ! [        [
        4 a
    SSU  34s $ f = f)u$   Valida si el valor es BIGINT válidor   r   l         l    FzValor fuera de rango BIGINT: r   r   r%   s     r   validar_bigint"ValidadorTiposDatos.validar_bigintK   s     775>>Ub[	F%,'G#wE2EE! F  =eWEEEI& 	F=eWEEE	Fr*   c                    [         R                  " U 5      (       d  U S:X  a  g [        U 5      n[        U5      nUR	                  SS5      R	                  SS5      nSU;   a.  UR                  S5      n[        US   5      n[        US   5      nO[        U5      nSnXqU-
  :  a  SS	U  S
X-
   S34$ XS-   :  a  SSU  SU SU S34$ X:  a   g! [         a  n	SS[        U	5       34s Sn	A	$ Sn	A	ff = f)u   
Valida si el valor cumple con DECIMAL(precision, escala)
PERMITE valores con más decimales y los trunca mentalmente

Args:
    valor: Valor a validar
    precision (int): Total de dígitos
    escala (int): Dígitos decimales
r   r   -+.r   r   Fu    Parte entera excede precisión: z (max u    dígitos enteros)d   zDemasiados decimales: z (tiene z, se esperaban max )zError validando decimal: N)r    r!   r"   strreplacesplitlen	Exception)
r&   	precisionescalavalor_float	valor_str	valor_abspartesdigitos_enterosdigitos_decimaleses
             r   validar_decimal#ValidadorTiposDatos.validar_decimalZ   s,    775>>Ub[%	?,K K(I "))#r2::3CI i"-"%fQi.$'q	N!"%i.$%! f"45 @viN^M__qrrr !SL1 6ugXFWEXXklrksstuuu !) 	?5c!fX>>>	?s*   BC 2C C 
C3C.(C3.C3c           	         [         R                  " U 5      (       d  U S:X  a  g [        U 5      R                  5       n[	        U5      U::  a  gSSU SUSS  S[	        U5       S	34$ ! [
         a  nSS
[        U5       34s SnA$ SnAff = f)z0Valida si el valor cumple con NVARCHAR(longitud)r   r   Fu   Excede longitud máxima de z: 'N2   z...' (longitud: r3   zError validando NVARCHAR: )r    r!   r4   r   r7   r8   )r&   longitudr<   rA   s       r   validar_nvarchar$ValidadorTiposDatos.validar_nvarchar   s     775>>Ub[	@E
((*I9~)! ;H:SSVTVHXXhilmviwhxxyzzz 	@6s1vh???	@s#   (A' A' '
B1B BBc                    [         R                  " U 5      (       d  U S:X  a  g/ SQn[        U 5      R                  5       nX!;   a  gUR	                  S5      (       d,  UR	                  S5      (       d  UR	                  S5      (       a  g [         R
                  " U SS9nUR                  S	:  a  S
SU  34$ g!   S
SU  34s $ = f)uN   Valida si el valor es DATETIME válido o un valor especial que representa NULLr   r   )z
00/01/1900z
00-01-1900z
1900-01-00z00:00:00z
0000-00-00z
00/00/0000z
01/01/1900z00/z00:z00-raise)errorsil  Fz#Fecha muy antigua (antes de 1900): u   No es una fecha válida: )r    r!   r4   r   
startswithto_datetimeyear)r&   valores_null_fechar<   fecha_parseadas       r   validar_datetime$ValidadorTiposDatos.validar_datetime   s     775>>Ub[
 J$$&	 * &&)*>*>u*E*EI]I]^cIdId
	>^^E'BN ""T) CE7KKK	>5eW===s   
+B7 7	Cc                 b    [         R                  " U 5      (       d  U S:X  a  gU S;   a  gSSU  34$ )u5   Valida si el valor es BIT válido (0, 1, True, False)r   r   )
r   r   01TFTrueFalsetruefalseFu   No es un valor BIT válido: )r    r!   )r&   s    r   validar_bitValidadorTiposDatos.validar_bit   s9     775>>Ub[SS8@@@r   Nc                 B   [         R                  " U5      =(       d6    US:H  =(       d*    [        U[        5      =(       a    UR	                  5       S:H  nU(       a  U(       a  X0R
                  ;   a  SSU S34$ U(       a  gU R                  U5      u  pVpxUS:X  a  U R                  U5      $ US:X  a  U R                  U5      $ US;   a  U R                  XU5      $ US	;   a  U R                  X5      $ US
;   a  U R                  U5      $ US:X  a  U R                  U5      $ g)uY  
Valida un valor según su tipo SQL Server
INCLUYE VALIDACIÓN DE COLUMNAS OBLIGATORIAS (NOT NULL)

Args:
    valor: Valor a validar
    tipo_sql (str): Tipo SQL como 'INT', 'NVARCHAR(50)', etc.
    nombre_columna (str): Nombre de la columna (para validar si es obligatoria)
    
Returns:
    tuple: (es_valido: bool, mensaje_error: str o None)
r   Fu"   ⚠️ Campo obligatorio vacío: 'u   ' no puede estar vacíor   INTBIGINT)DECIMALNUMERIC)NVARCHARVARCHARCHARNCHAR)DATETIME	DATETIME2DATESMALLDATETIMEBIT)r    r!   
isinstancer4   r   COLUMNAS_OBLIGATORIASr   r(   r,   rB   rG   rQ   rZ   )	clsr&   r   nombre_columna
esta_vacio	tipo_baserF   r9   r:   s	            r   validar_por_tipo_sql(ValidadorTiposDatos.validar_por_tipo_sql   s    WWU^fu{fz%7M7eRWR]R]R_ceRe
.^?X?X-X>~>NNefff  251J1J81T.	Y ??5))("%%e,,00&&u@@BB''88LL''..%??5)) r    N)__name__
__module____qualname____firstlineno____doc__rk   staticmethodr   r(   r,   rB   rG   rQ   rZ   classmethodrp   __static_attributes__rr   r   r   r   r      s     	 * *: F F F F 2? 2?h @ @ %> %>N A A / /r   r   c           
      <   / nU R                    H-  nX   R                  S:X  d  M  X   R                  S 5      X'   M/     U R                    H-  nX   R                  S;   d  M  X   R                  S 5      X'   M/     SnX0R                   ;   a  [        U 5      nX   R	                  5       X   S:H  -  nX   R
                  R                  5       nU H!  nUR                  US-   USS	S
U S3S.5        M#     X)    n [        U 5      nXH-
  n	[        SU SU	 35        X4$ )u   
Limpia y prepara el DataFrame según las especificaciones

Args:
    df (pd.DataFrame): DataFrame a limpiar
    
Returns:
    tuple: (pd.DataFrame limpio, list de filas eliminadas con detalle)
objectc                 P    [        U [        5      (       a  U R                  5       $ U $ rs   )rj   r4   r   xs    r   <lambda>#limpiar_dataframe.<locals>.<lambda>  s    :a;M;Maggi.TST.Tr   )float64int64c                 T    [         R                  " U 5      (       a  [        U S5      $ U $ )N   )r    notnaroundr   s    r   r   r     s    bhhqkkeArl.Pq.Pr   r	   r   r   u   [VACÍO]zNOT NULLu    ⚠️ Eliminar Fila completa: 'u"   ' está vacío (campo obligatorio))filacolumnar&   tipo_esperadoerrorzFilas eliminadas por u    nulo/vacío: )	columnsdtypeapplyr7   r!   indextolistappendprint)
dffilas_eliminadas_detallecolcolumna_obligatoriafilas_antesmask_vaciasindices_vaciasidxfilas_despuesfilas_eliminadass
             r   limpiar_dataframer     s>     " zz7==H$gmm$TUBG 
 zz7==00gmm$PQBG 
 *jj("g -2248OSU8UV..557 "C$++a.#!+;<O;PPrs-  " B&6%&9%:.IYHZ[\''r   )rx   pandasr    numpynpr   r   decimalr   r   r   r   rr   r   r   <module>r      s-      	  -q qh1(r   