
    tz0ix              
          S SK r S SKrS SKJr  S SKJrJrJrJr  \R                  " S5      r	S SK
JrJr  S SKJr  S rS\S	\\   4S
 jrS\S	\\   4S jrS\S\S\S	\4S jrS\S\S\S	\4S jrS rS\S\\   S	\4S jrS\S\S\S\S	\4
S jrS\S	\4S jrS\S	\4S jrS rS\S	\4S jrS\S	\4S jrS\S \S	\ 4S! jr!g)"    N)datetime)DictListOptionalUnioncotizaciones_especiales_sql)
ProductivoENVIRONMENT)get_connectionc                 L   SnSU UUSS4nSnSn [        5       nU(       d3   U(       a   UR                  5         U(       a   UR                  5         ggUR                  5       nUR                  X45        UR	                  5       nUR                  5         U(       aP  US   n[        R                  SU 35        UU(       a   UR                  5         U(       a   UR                  5         $ $  U(       a   UR                  5         U(       a   UR                  5         gg!    N= f!    g= f!    N_= f!    $ = f!    N:= f!    g= f! [         a  n	[        R                  S[        U	5       35        U(       a   UR                  5         O!    O= f Sn	A	U(       a   UR                  5         O!    O= fU(       a   UR                  5         g!    g= fgSn	A	ff = f! U(       a   UR                  5         O!    O= fU(       a   UR                  5         f !    f = ff = f)u   
Inserta un registro en Q_CRM usando solo:
- contactName
- contactNumber
- contactEmail

Y devuelve el nuevo CRM_OpportunityNumber (identity).

Returns:
    Optional[int]: Nuevo OpportunityNumber si se insertó, None si hubo error.
aQ  
        INSERT INTO Q_CRM (
            CRM_Version,
            CRM_ContactName,
            CRM_ContactNumber,
            CRM_ContactEmail,
            Status,
            CreatedAt,
            CreatedBy,
            Active
        )
        OUTPUT INSERTED.CRM_OpportunityNumber
        VALUES (?, ?, ?, ?, ?, GETDATE(), ?, 1)
       SYSTEMNr   u-   ✅ CRM Contact insertado: OpportunityNumber=u$   ❌ Error al insertar contacto CRM: )r   closecursorexecutefetchonecommitloggerinfo	Exceptionerrorstrrollback)
contactNamecontactNumbercontactEmailqueryparamsconnr   rowopportunity_numberes
             nC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\Consultas_SQL\Ventas\Cotiz\CotizEspSolicitudSQL.pyinsert_CRM_CONTACTr$      s   E  	
	F DF(8  

 ? u% oo 	!$QKKGHZG[\]%  

 #   

 '  ;CF8DE 

	  

	 s   E	 D D& A&E	 D-D45D; E D#&D*-D14D8;D?E	
G(G<FGFGG!  F1 1F5 G GGG! !H#*G;:H#;G?=H#
HH#HH#r!   returnc                    [        SU  35        Sn[        SU  35        [        SU 35        Sn [        5       nU(       d  [        S5      eU   UR                  5       nUR	                  X45        UR
                   Vs/ s H  oDS   PM	     nnUR                  5       nU(       aw  [        [        XV5      5      n[        R                  SU  S35        S	U;   a   US	   (       a  US	   R                  5       US	'   UsSSS5        U(       a   UR                  5         $ $ [        R                  SU  S
35         SSS5        U(       a   UR                  5         ggs  snf !    $ = f!    g= f! , (       d  f       O= f! [        R                   a6  nSU  S[!        U5       3n	[        R#                  U	5        [%        U	5      eSnAf[         a6  nSU  S[!        U5       3n	[        R#                  U	5        [        U	5      eSnAf[$         a6  nSU  S[!        U5       3n	[        R#                  U	5        [%        U	5      eSnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)uk  
Busca una oportunidad en la tabla Q_OpportunityCRM

Args:
    opportunity_number (float): Número de oportunidad del CRM

Returns:
    Dict: Diccionario con los datos de la oportunidad si se encuentra, None si no existe
    
Raises:
    ConnectionError: Si no se puede establecer conexión con la base de datos
    Exception: Para otros errores de base de datos
u%   🔍 DEBUG - Buscar oportunidad CRM: a<  
        SELECT TOP 1
            Q_CRM.CRM_OpportunityNumber,
            Q_CRM.CRM_Version,
            Q_CRM.CRM_ContactID,
            Q_CRM.CRM_ContactName,
            Q_CRM.CRM_ContactType,
            Q_CRM.CRM_AssignedSalesperson,
            Q_CRM.CRM_ContactAdress,
            Q_CRM.CRM_ContactColonia,
            Q_CRM.CRM_ContactCity,
            Q_CRM.CRM_ContactNumber,
            Q_CRM.CRM_ContactCountry,
            Q_CRM.CRM_ContactLegalIdentifier,
            Q_CRM.CRM_ContactZip,
            Q_CRM.CRM_ContactState,
            Q_CRM.CRM_ContactEmail,
            Q_CRM.Status,
            Q_CRM.CreatedAt,
            Q_CRM.CreatedBy,
            Q_CRM.Active
        FROM Q_CRM
        WHERE Q_CRM.CRM_OpportunityNumber = ?
            AND Q_CRM.Active = 1
        ORDER BY Q_CRM.CRM_Version DESC
    u   🔍 DEBUG - Query: N4   No se pudo establecer conexión con la base de datosr   Oportunidad z encontrada exitosamente	CreatedAtz" no encontrada en la base de datosz-Error de base de datos al buscar oportunidad : u)   Error de conexión al buscar oportunidad z'Error inesperado al buscar oportunidad )printr   ConnectionErrorr   r   descriptionr   dictzipr   r   	isoformatr   warningpyodbcErrorr   r   r   )
r!   r   r   r   columncolumnsr    resultr"   	error_msgs
             r#   buscar_oportunidad_crmr8   f   s    
12D1E
FGE4 
12D1E
FG	 
()D9!"XYY[[]FNN5"78 06/A/AB/AVay/AGB //#Cc'/0 l+=*>>VWX &(VK-@*0*=*G*G*IF;'+ T^ 

 / .@-AAcde3 ^ 

 U CZg T6 << #CDVCWWYZ]^_Z`Yab	Y	"" )?@R?SSUVYZ[V\U]^	Yi(( #=>P=QQSTWXYTZS[\	Y	""	#O ^ 

	 4

	 s   E= 1E,?EA-E,:	E= EE,7E= E% E,E"%E),
E:6E= 9I( :E= =I1GI1H  I1H>>II( I   I$(J
1JJ
JJ
c           	      ,   SnSn [        5       nU(       d  [        S5      eU   UR                  5       nUR                  X45        UR                   Vs/ s H  oDS   PM	     nnUR                  5       nU(       a  [        [        XV5      5      nUR                  SS5      R                  5       nUS;   a*  [        R                  SU  S	U S
35        [        SU 35      eUS;   a*  [        R                  SU  S	U S35        [        SU 35      e[        R                  SU  SUS    SU 35        UsSSS5        U(       a   UR                  5         $ $ [        R                  SU  S35         SSS5        U(       a   UR                  5         ggs  snf !    $ = f!    g= f! , (       d  f       O= f! [         a  n	U	eSn	A	f[        R                    a6  n	SU  S[#        U	5       3n
[        R%                  U
5        ['        U
5      eSn	A	f[&         a6  n	SU  S[#        U	5       3n
[        R%                  U
5        ['        U
5      eSn	A	ff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)u  
Verifica si ya existe una oportunidad y retorna la versión más alta
También valida que no esté cerrada/vendida o en proceso activo

Args:
    opportunity_number (str): Número de oportunidad del CRM

Returns:
    Dict: Datos de la oportunidad existente con versión más alta, None si no existe
    
Raises:
    Exception: Si la oportunidad está cerrada/vendida o en proceso activo
a  
        SELECT TOP 1
            Q_OpportunityCRM.CRM_OpportunityNumber,
            Q_OpportunityCRM.Version,
            Q_OpportunityCRM.CRM_OpportunityID,
            Q_OpportunityCRM.Status,
            Q_OpportunityCRM.Active
        FROM Q_OpportunityCRM
        WHERE Q_OpportunityCRM.CRM_OpportunityNumber = ?
            AND Q_OpportunityCRM.Active = 1
        ORDER BY Q_OpportunityCRM.Version DESC
    Nr'   r   Status )VENDIDOVENDIDAATENDIDOr(   z tiene status z - proceso terminadozOPPORTUNITY_CLOSED:)	PENDIENTEzEN DESARROLLOzEN APROBACIONEN_DESARROLLOEN_APROBACIONz - proceso activozOPPORTUNITY_IN_PROCESS:u    encontrada con versión Versionz
 y status z no encontradaz0Error de base de datos al verificar oportunidad r*   z*Error inesperado al verificar oportunidad )r   r,   r   r   r-   r   r.   r/   getupperr   r1   
ValueErrorr   r   r2   r3   r   r   r   )r!   r   r   r   r4   r5   r    r6   statusr"   r7   s              r#   verificar_oportunidad_existenterG      s   E D5!"XYY[[]FNN5"78/5/A/AB/AVay/AGB//#Cc'/0  Hb1779 ??NN\2D1E^TZS[[o#pq$':6(%CDD nnNN\2D1E^TZS[[l#mn$'>vh%GHHl+=*>>WX^_hXiWjjtu{t|}~1 TX 

 % l+=*>nMN7 X 

 Q CVa T:  << #FGYFZZ\]`ab]c\de	Y	"" #@AS@TTVWZ[\W]V^_	Y	""#M X 

	 4

	 s   F5 1F$F#CF$2	F5 FF$/F5 ?F F$FF!$
F2.F5 1I1 2F5 5
I?GI1H		I1III1 I) )I-1J:J
JJJdatos_oportunidaduser_idversionc                    [        U5      nSnSn [        5       nU(       d  [        S5      eU   UR                  5       nUR	                  UU R                  SS5      UUU R                  SS5      U R                  SS5      U R                  SS5      U R                  S	S5      U R                  S
S5      U R                  SS5      U R                  SS5      U R                  SS5      U R                  SS5      U R                  SS5      U R                  SS5      U R                  SS5      U R                  SS5      SUU45        UR                  5         U R                  S5       SU 3n[        R                  SU S35        SUS.sSSS5        U(       a   UR                  5         $ $ !    $ = f! , (       d  f       O= f! [        R                   aU  nS[        U5       3n	[        R                  U	5        SSSSSS.s SnAU(       a   UR                  5         $ !    $ = f$ SnAf[         aU  nS [        U5       3n	[        R                  U	5        SS!S"SSS.s SnAU(       a   UR                  5         $ !    $ = f$ SnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)#u   
Crea o actualiza un registro en Q_OpportunityCRM

Args:
    datos_oportunidad (Dict): Datos de la oportunidad
    user_id (int): ID del usuario
    version (int): Versión de la oportunidad

Returns:
    Dict: Resultado de la operación
a  
        INSERT INTO Q_OpportunityCRM (
            CRM_OpportunityNumber,
            Version,
            UserID,
            CRM_ContactID,
            CRM_ContactName,
            CRM_ContactType,
            CRM_AssignedSalesperson,
            CRM_ContactAdress,
            CRM_ContactColonia,
            CRM_ContactCity,
            CRM_ContactNumber,
            CRM_ContactCountry,
            CRM_ContactLegalIdentifier,
            CRM_ContactZip,
            CRM_ContactState,
            CRM_ContactEmail,
            Status,
            CreatedBy,
            UpdatedBy
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    Nr'   CRM_OpportunityNumberr;   CRM_ContactIDCRM_ContactNameCRM_ContactTypeCRM_AssignedSalespersonCRM_ContactAdressCRM_ContactColoniaCRM_ContactCityCRM_ContactNumberCRM_ContactCountryCRM_ContactLegalIdentifierCRM_ContactZipCRM_ContactStateCRM_ContactEmailr?   -r(   z creada exitosamenteT)successopportunity_idz-Error de base de datos al crear oportunidad: Fz,Error al guardar los datos de la oportunidadDATABASE_ERRORr   i  )r[   messagecode
alert_typestatus_codez'Error inesperado al crear oportunidad: z(Error interno al procesar la oportunidadINTERNAL_ERROR)obtener_nombre_usuarior   r,   r   r   rC   r   r   r   r   r2   r3   r   r   r   )
rH   rI   rJ   	user_namer   r   r   r\   r"   r7   s
             r#   crear_actualizar_oportunidadre   $  s    'w/IE0 DA!"XYY[[]FNN5!%%&=rB!%%or:!%%&7<!%%&7<!%%&?D!%%&92>!%%&:B?!%%&7<!%%&92>!%%&:B?!%%&BBG!%%&6;!%%&8"=!%%&8"='# , KKM 1 5 56M NOqQXPYZNKK,~&66JKL"09 Tp 

 y TB << 	
CCF8L	YE$!
 	
( 

	   	
=c!fXF	YA$!
 	
 

	 	
Y p 

	 4

	 s   G EF2	G F++F/2
G <G ?J.  G J	*H'J	J. HH#'J	4*JJ	J. +I<<J J		J. J& &J*.K7KKK
Kr\   quotation_type_idc           	         [        U5      nSnSn [        5       nU(       d  [        S5      eU   UR                  5       nUR	                  UU UUUU45        UR                  5         U  SU 3n[        R                  SU S35        SUS.sSSS5        U(       a   UR                  5         $ $ !    $ = f! , (       d  f       O= f! [        R                   aT  nS	[        U5       3n	[        R                  U	5        S
SSSS.s SnAU(       a   UR                  5         $ !    $ = f$ SnAf[         aT  nS[        U5       3n	[        R                  U	5        S
SSSS.s SnAU(       a   UR                  5         $ !    $ = f$ SnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)u   
Crea un registro en Q_SpQ_FormsHead

Args:
    opportunity_id (str): ID de la oportunidad
    quotation_type_id (str): ID del tipo de cotización
    user_id (int): ID del usuario

Returns:
    Dict: Resultado de la operación
z
        INSERT INTO Q_SpQ_FormsHead (
            CRM_OpportunityID,
            QuotationTypeID,
            UserID,
            CreatedBy,
            UpdatedBy
        ) VALUES (?, ?, ?, ?, ?)
    Nr'   rZ   z	FormHead z creado exitosamenteT)r[   form_idz*Error de base de datos al crear FormHead: Fz%Error al crear registro de formularior]   r   r[   r^   r_   r`   z$Error inesperado al crear FormHead: z!Error interno al crear formulariorb   )rc   r   r,   r   r   r   r   r   r   r2   r3   r   r   r   )
r\   rf   rI   rd   r   r   r   rh   r"   r7   s
             r#   crear_formulario_headrj     s    'w/IE D1!"XYY[[]FNN5!#  KKM'(*;)<=GKK)G9,@AB" TP 

 Y T& << 
@QI	Y>$!	
 	
$ 

	   
:3q6(C	Y:$!	
 	
 

	 
; P 

	 4

	 s   C AB5	C B..B25
C?C F/ C F
)D)F
F/ D!!D%)F
6)FF
 F/ ,E==FF

F/ F' 'F+/G8G	G	GGc                     g )N )opportunitus    r#   getDocsUploadedFromOpportunityrn     s        rh   	preguntasc                    [        SU  35        [        S[        U5       35        [        U5       H  u  p#[        SUS-    SU 35        M     SnSn [        5       nU(       d  [	        S5      eS	nU   UR                  5       n[        USS
9 H  u  p[        U5      R                  S5      n	[        SU S35        [        SU  35        [        SU	 35        [        SUS    35        [        SUS    35        [        SUS    35        [        SU  SU	 35        UR                  UU U	US   US   US   45        US-  n[        SU S35        M     UR                  5         [        R                  SU SU  35        SUS.sSSS5        U(       a   UR                  5         $ $ !    $ = f! , (       d  f       O= f! [        R                   ab  n
S[        U
5       3n[        R                  U5        [        SU 35        S S!S"S#S$.s Sn
A
U(       a   UR                  5         $ !    $ = f$ Sn
A
f[          ab  n
S%[        U
5       3n[        R                  U5        [        S&U 35        S S'S(S#S$.s Sn
A
U(       a   UR                  5         $ !    $ = f$ Sn
A
ff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f))u   
Crea múltiples registros en Q_SpQ_FormsDetail

Args:
    form_id (str): ID del formulario
    preguntas (List[Dict]): Lista de preguntas y respuestas

Returns:
    Dict: Resultado de la operación
u   🔍 DEBUG - FormID: u   🔍 DEBUG - Total preguntas: u   🔍 DEBUG - Pregunta r   r*   z
        INSERT INTO Q_SpQ_FormsDetail (
            FormID,
            FormLine,
            Question,
            TypeQuestion,
            Answer
        ) VALUES (?, ?, ?, ?, ?)
    Nr'   r   )start   u!   🔍 DEBUG - Insertando registro :z    FormID: z    FormLine: z    Question: preguntaz    TypeQuestion: tipoElementoz    Answer: 	respuestaz    Expected FormLineID: rZ   u   ✅ DEBUG - Registro z insertado exitosamentezCreados z detalles para FormID T)r[   records_createdz-Error de base de datos al crear FormDetails: u   ❌ DEBUG - Error SQL: Fz(Error al guardar detalles del formularior]   r   ri   z'Error inesperado al crear FormDetails: u   ❌ DEBUG - Error general: z!Error interno al guardar detallesrb   )r+   len	enumerater   r,   r   r   zfillr   r   r   r   r   r2   r3   r   r   )rh   rp   iru   r   r   registros_creadosr   index	form_liner"   r7   s               r#   crear_formulario_detailsr     s.    
!'
+,	*3y>*:
;< +&qse2hZ89 ,E DD!"XYY[[]F $-Ya#@J,,Q/	 9%BCWI./yk23x
';&<=>*8N+C*DEFXk%:$;<=1'!I;GHuZ(^,[)'  "Q&!-eW4KLM) $A, KKMKK(#4"55KG9UV#4; Tr 

 { TD << 	
CCF8L	Y'	{34A$!	
 	
& 

	   	
=c!fXF	Y+I;78:$!	
 	
 

	 	
[ r 

	 4

	 s    F> 3DF-	F> F&&F*-
F;7F> :K ;F> >J7H/	J
K H''H+/J<7J3J4K  JJJK *J; ;J?K%KK%K!K%seller_user_idrd   c           	         SnSn [        5       nU(       d  [        S5      eU   UR                  5       nUR                  UU USUU45        UR                  S5        UR	                  5       S   nUR                  5         [        R                  SU SU 35        S	US
.sSSS5        U(       a   UR                  5         $ $ !    $ = f! , (       d  f       O= f! [        R                   aT  nS[        U5       3n	[        R                  U	5        SSSSS.s SnAU(       a   UR                  5         $ !    $ = f$ SnAf[         aT  nS[        U5       3n	[        R                  U	5        SSSSS.s SnAU(       a   UR                  5         $ !    $ = f$ SnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)u  
Crea una tarea en Q_SpQ_QuotationTasks

Args:
    seller_user_id (int): ID del vendedor
    form_id (str): ID del formulario
    opportunity_id (str): ID de la oportunidad
    user_name (str): Nombre del usuario que crea la tarea

Returns:
    Dict: Resultado de la operación
a4  
        INSERT INTO Q_SpQ_QuotationTasks (
            SellerUserID,
            FormID,
            Status,
            StatusDate,
            CRM_OpportunityID,
            UpdatedBy
        ) VALUES (?, ?, ?, CAST(SYSDATETIMEOFFSET() AT TIME ZONE 'Central America Standard Time' AS DATETIME), ?, ?)
    Nr'   zPor AsignarzSELECT @@IDENTITY AS TaskIDr   zTarea z creada para FormID T)r[   task_idz'Error de base de datos al crear tarea: Fu#   Error al crear tarea de cotizaciónr]   r   ri   z!Error inesperado al crear tarea: zError interno al crear tarearb   )r   r,   r   r   r   r   r   r   r   r2   r3   r   r   r   )
r   rh   r\   rd   r   r   r   r   r"   r7   s
             r#   crear_tarea_cotizacionr   F  s   	E D4!"XYY[[]FNN5#  NN89oo'*GKKMKK&	)=gYGH"# TV 

 _ T, << 
=c!fXF	Y<$!	
 	
$ 

	   
7Ax@	Y5$!	
 	
 

	 
A V 

	 4

	 s   C A;C		C 0CC	
CC G C F.)D=FG $D55D9=F
)F3F4G  FFFG *F; ;F?G%GG%G!G%c           	         SnSn [        5       nU(       d  SU  3U(       a   UR                  5         $ $ U   UR                  5       nUR                  X45        UR	                  5       nU(       a`  SR                  US   R                  5       5      nUR                  5       (       a  UOSU  3sSSS5        U(       a   UR                  5         $ $ SU  3sSSS5        U(       a   UR                  5         $ $ !    $ = f!    $ = f!    $ = f! , (       d  f       Oc= f! [         aS  n[        R                  SU  S[        U5       35        SU  3s SnAU(       a   UR                  5         $ !    $ = f$ SnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)z
Obtiene el nombre completo del usuario desde la tabla Profiles

Args:
    user_id (int): ID del usuario

Returns:
    str: Nombre completo del usuario
a  
        SELECT 
            CONCAT(
                COALESCE(Profiles.FirstName, ''), ' ',
                COALESCE(Profiles.LastName, ''), ' ',
                COALESCE(Profiles.SecondLastName, '')
            ) AS FullName
        FROM Profiles
        WHERE Profiles.UserID = ?
            AND Profiles.UserID IN (
                SELECT Users.UserID 
                FROM Users 
                WHERE Users.Status = 'ACTIVO'
            )
    NUsuario_ r   z#Error al obtener nombre de usuario r*   )r   r   r   r   r   joinsplitstripr   r   r1   r   )rI   r   r   r   r    	full_namer"   s          r#   rc   rc     s   E  DgY'& 

 # [[]FNN5*-//#CHHSV\\^4	$-OO$5$5yXgY;O T" 

  "'+ T" 

 + T  $<WIRAxPQ'## 

	 $ " 

	 4

	 s   D C8D A7D.	D ?C?D	D &D8C<?DD

DD F  D 
E;((E6E;F  E..E26E;;F  F F G)F:9G:F><Gc           	      n   SnSn [        5       nU(       d3  [        R                  SU  35         U(       a   UR                  5         ggU   UR	                  5       nUR                  X45        UR                  5       nU(       aM  [        US   5      n[        R                  SU  SU 35        UsSSS5        U(       a   UR                  5         $ $ [        R                  SU  S35         SSS5        U(       a   UR                  5         gg!    g= f!    $ = f!    g= f! , (       d  f       O= f! [        R                   aN  n[        R                  S	U  S
[        U5       35         SnAU(       a   UR                  5         g!    g= fgSnAf[         aN  n[        R                  SU  S
[        U5       35         SnAU(       a   UR                  5         g!    g= fgSnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)u   
Consulta si un tipo de formulario debe crear tarea en Q_SpQ_QuotationTasks

Args:
    quotation_type_id (str): ID del tipo de cotización

Returns:
    bool: True si debe crear tarea, False si no
z
        SELECT Q_QuotationType.CreateTask
        FROM Q_QuotationType
        WHERE Q_QuotationType.QuotationTypeID = ?
            AND Q_QuotationType.Active = 1
    Nz1No se pudo conectar para verificar CreateTask de Tr   zQuotationType z - CreateTask: z no encontradoz)Error de BD al consultar CreateTask para r*   z.Error inesperado al consultar CreateTask para )r   r   r1   r   r   r   r   boolr   r2   r3   r   r   r   )rf   r   r   r   r    create_taskr"   s          r#   debe_crear_tarear     s"   E D NNNO`Nabc0 

 - [[]FNN5"67//#C"3q6ln->,?{m\]" T, 

  0A/B.QR , 

 5 T << @AR@SSUVYZ[V\U]^_ 

	   EFWEXXZ[^_`[aZbcd 

	 # , 

	 4

	 s   )D5 D 
D5 A$D$0	D5 DD$-D5 =D DDD!$
D2.D5 1H 2D5 5G-	$F-H 9F
 
FG-$G(H G   G$(G--H 9H
 
HH4H,+H4,H0.H4c           	          SnSn [        5       nU(       d   U(       a   UR                  5         ggU   UR                  5       nUR                  X45        UR	                  5       nU(       a'  US   sSSS5        U(       a   UR                  5         $ $  SSS5        U(       a   UR                  5         gg!    g= f!    $ = f!    g= f! , (       d  f       O^= f! [
         aN  n[        R                  SU  S[        U5       35         SnAU(       a   UR                  5         g!    g= fgSnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)z
Obtiene el TaskID asociado a un FormID en Q_SpQ_QuotationTasks

Args:
    form_id (str): ID del formulario

Returns:
    Optional[int]: TaskID si existe, None si no
z
        SELECT TOP 1
        Q_SpQ_QuotationTasks.FormID
        FROM Q_SpQ_QuotationTasks
        WHERE Q_SpQ_QuotationTasks.taskID = ?
    Nr   z$Error al obtener TaskID para FormID r*   )	r   r   r   r   r   r   r   r1   r   )taskIDr   r   r   r    r"   s         r#   get_FormID_by_TaskIDr     sp   E D" 

  [[]FNN5),//#C1v T 

    

 ' T  =fXRAxPQ 

	   

	 4

	 s   C B8 C >C2	C B?CC &C 8B<?CC

CC E C 
D6($D1E D) )D-1D66E E EE=$E54E=5E97E=tipo_formularioc                 B    SSSSSSSSS	S
SS.nUR                  U S5      $ )z
Mapea el tipo de formulario al QuotationTypeID correspondiente

Args:
    tipo_formulario (str): Tipo de formulario del frontend

Returns:
    str: QuotationTypeID correspondiente
FormGralFormSolicVisFormPTTransNacFormPTTransULFormAireFormSistCritUPSFormBess	FormSolar
FormEneCog	FormImessFormProyecEsp)GeneralSolicVis
PTTransNac	PTTransULAireSistCritUPSBessSolarEnergyCogenerationImess	ProyecEsp)rC   )r   mapeo_tiposs     r#   obtener_quotation_type_idr   2  s?     "&$(*$K ???J77ro   c           	      ,   SnSn [        5       nU(       d  U U(       a   UR                  5         $ $ U   UR                  5       nUR                  X45        UR	                  5       nU(       a:  US   (       a0  [        US   5      sSSS5        U(       a   UR                  5         $ $ U sSSS5        U(       a   UR                  5         $ $ !    $ = f!    $ = f!    $ = f! , (       d  f       O`= f! [         aP  n[        R                  SU  S[        U5       35        U s SnAU(       a   UR                  5         $ !    $ = f$ SnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)z
Obtiene el SellerUserID desde la tabla Profiles
Para vendedores directos, retorna el mismo user_id
Para distribuidores, retorna el SellerUserID asignado

Args:
    user_id (int): ID del usuario actual

Returns:
    int: ID del vendedor asignado
z
        SELECT 
            COALESCE(Profiles.SellerUserID, Profiles.UserID) AS SellerID
        FROM Profiles
        WHERE Profiles.UserID = ?
    Nr   z+Error al obtener SellerUserID para usuario r*   )
r   r   r   r   r   intr   r   r1   r   )rI   r   r   r   r    r"   s         r#   obtener_seller_user_idr   M  s   E D" 

  [[]FNN5*-//#Cs1v3q6{ T 

   T 

 ' T  DWIRPSTUPVxXY 

	   

	 4

	 s   C2 CC2 AC!	C2 C(C!)	C2 :CCCC!
C/+C2 .E1 /C2 2
E<%E!E"E1 .D??EEE1 E) )E-1F:F
FFFdocs_idc                 ,   SnSn [        5       nU(       d  [        S5      eU   UR                  5       nUR                  X!U 45        UR                  nUR                  5         US:  aA  [        R                  SU  SU 35        SS0sSSS5        U(       a   UR                  5         $ $ [        R                  S	U  S
35        SSS.sSSS5        U(       a   UR                  5         $ $ !    $ = f!    $ = f! , (       d  f       O= f! [        R                   aS  nS[        U5       3n[        R                  U5        SSSS.s SnAU(       a   UR                  5         $ !    $ = f$ SnAf[         aS  nS[        U5       3n[        R                  U5        SSSS.s SnAU(       a   UR                  5         $ !    $ = f$ SnAff = f U(       a   UR                  5         g!    g= fg! U(       a   UR                  5         f !    f = ff = f)u   
Actualiza el formulario con el DocsID generado

Args:
    form_id (str): ID del formulario
    docs_id (int): ID del grupo de documentos

Returns:
    dict: Resultado de la operación
zp
        UPDATE Q_SpQ_FormsHead 
        SET DocsID = ?
        WHERE FormID = ?
            AND Active = 1
    Nr'   r   zFormulario z actualizado con DocsID r[   Tu   No se encontró formulario z para actualizarFz(Formulario no encontrado para actualizar)r[   r^   z1Error de base de datos al actualizar formulario: z-Error al actualizar formulario con documentosr]   )r[   r^   r_   z+Error inesperado al actualizar formulario: z&Error interno al actualizar formulariorb   )r   r,   r   r   rowcountr   r   r   r   r1   r2   r3   r   r   r   )rh   r   r   r   r   rows_affectedr"   r7   s           r#   actualizar_formulario_con_docsr   |  s   E D-!"XYY[[]FNN5G"45"OOMKKMq k'2J7)TU!4( TH 

 3 !<WIEUVW$I TH 

 Q T" << 
GAxP	YF$
 	
  

	   
A#a&J	Y?$
 	
 

	 
5 H 

	 4

	 s   D
 A$C9	D
 C++C9	D
 C2+C/2C69
DD
 G1 D
 
G(E,GG1 E$$E(,G9(G!G"G1 .F??GGG1 G) )G-1H:H
HHH)"r2   loggingr   typingr   r   r   r   	getLoggerr   configr	   r
   Consultas_SQL.conexionr   r$   floatr8   r   rG   r   re   rj   rn   r   r   rc   r   r   r   r   r   r.   r   rl   ro   r#   <module>r      s      . . 
		8	9 * 1Ofgu g$ gTR R RhjD j3 jQT jY] jZK# K# KPS KX\ K\	ac ad4j aT aFN3 N Nc N^a Nfj N`6C 6C 6p3 3 3n+Z8s 8s 86-C -C -^AC A# A$ Aro   