+
    iw                     
   ^ RI t ^ RIt^ RIHt ^ RIHtHtHtHt ]P                  ! R4      t	^ RI
HtHt ^ RIHt R tR R	 ltR
 R ltR R ltR R ltR R ltR R ltR R ltR R ltR tR R ltR R ltR R ltR# )    N)datetime)DictListOptionalUnioncotizaciones_especiales_sql)
ProductivoENVIRONMENT)get_connectionc                   Rp^V VV^R3pRpRp \        4       pV'       g8    V'       d    VP                  4        V'       d    VP                  4        R# R# VP                  4       pVP                  W44       VP	                  4       pVP                  4        V'       dW   V^ ,          p\        P                  RV 24       TV'       d    VP                  4        V'       d    VP                  4        # #  V'       d    VP                  4        V'       d    VP                  4        R# R#     L; i    R# ; i    Le; i    # ; i    L>; i    R# ; i  \         d   p	\        P                  R\        T	4       24       T'       d    TP                  4        M    M; i Rp	?	T'       d    TP                  4        M    M; iT'       d    TP                  4        R#     R# ; iR# Rp	?	ii ; i  T'       d    TP                  4        M    M; iT'       d    TP                  4        i     i ; ii ; i)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)
    SYSTEMNu-   ✅ 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/ D6 A+E D>&EE E /D36D;>EE	EEG7&)G2F! G2!F%#G2(G: 5G G
G( (G-2G77G: :	H>HH>HH>%H65H>6H:8H>c                F    V ^8  d   QhR\         R\        \        ,          /#    r    return)floatr   r   )formats   "r"   __annotate__r*   f   s"     g gu g$ g    c                h   \        RV  24       Rp\        RV  24       \        RV 24       Rp \        4       pV'       g   \        R4      hT;_uu_ 4        VP                  4       pVP	                  W34       VP
                   Uu. uF  qD^ ,          NK  	  ppVP                  4       pV'       d   \        \        WV4      4      p\        P                  RV  R24       RV9   d*   VR,          '       d   VR,          P                  4       VR&   TuuRRR4       V'       d    VP                  4        # # \        P                  RV  R	24        RRR4       V'       d    VP                  4        R# R# u upi     # ; i    R# ; i  + '       g   i     M; i  \        P                   d7   pR
T  R\!        T4       2p	\        P#                  T	4       \%        T	4      hRp?i\         d7   pRT  R\!        T4       2p	\        P#                  T	4       \        T	4      hRp?i\$         d7   pRT  R\!        T4       2p	\        P#                  T	4       \%        T	4      hRp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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 datos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_crmr>   f   s    
12D1E
FGE4 
12D1E
FG	 
()D9!"XYYT[[]FNN5"78 06/A/AB/AVayy/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   'F 1F	E5AF	6F	
F $E:6F	F !F 5F	:E>F	F	F J F I%11G""I%/I%01H!!I%.I%/1I  I%%J 2J J		J1J)(J1)J-+J1c                F    V ^8  d   QhR\         R\        \        ,          /# r%   )r   r   r   )r)   s   "r"   r*   r*      s"     R R R Rr+   c           
     r   RpRp \        4       pV'       g   \        R4      hT;_uu_ 4        VP                  4       pVP                  W34       VP                   Uu. uF  qD^ ,          NK  	  ppVP                  4       pV'       d   \        \        WV4      4      pVP                  RR4      P                  4       pVR9   d+   \        P                  RV  RV R24       \        R	V 24      hVR9   d+   \        P                  RV  RV R
24       \        RV 24      h\        P                  RV  RVR,           RV 24       TuuRRR4       V'       d    VP                  4        # # \        P                  RV  R24        RRR4       V'       d    VP                  4        R# R# u upi     # ; i    R# ; i  + '       g   i     M; i  \         d   p	T	hRp	?	i\        P                    d7   p	RT  R\#        T	4       2p
\        P%                  T
4       \'        T
4      hRp	?	i\&         d7   p	RT  R\#        T	4       2p
\        P%                  T
4       \'        T
4      hRp	?	ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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-   Status r.   z tiene status z - proceso terminadozOPPORTUNITY_CLOSED:z - proceso activozOPPORTUNITY_IN_PROCESS:u    encontrada con versión Versionz
 y status z no encontradaz0Error de base de datos al verificar oportunidad r0   z*Error inesperado al verificar oportunidad )VENDIDOVENDIDAATENDIDO)	PENDIENTEzEN DESARROLLOzEN APROBACIONEN_DESARROLLOEN_APROBACION)r   r2   r   r   r3   r   r4   r5   getupperr   r7   
ValueErrorr   r   r8   r9   r   r   r   )r    r   r   r   r:   r;   r   r<   statusr!   r=   s   &          r"   verificar_oportunidad_existenterN      s   E D5!"XYYT[[]FNN5"78/5/A/AB/AVayy/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   'G 1F=F)/CF=
G F.*F=G F5 )F=.F25F:=G	G J G I*GI*4I*51H&&I*3I*41I%%I**J 7J	 	J	J6J.-J6.J20J6c                H    V ^8  d   QhR\         R\        R\        R\         /# )r&   datos_oportunidaduser_idversionr'   )r   int)r)   s   "r"   r*   r*   $  s0     j jD j3 jQT jY] jr+   c                   \        V4      pRpRp \        4       pV'       g   \        R4      hV;_uu_ 4        VP                  4       pVP	                  VV P                  RR4      VVV P                  RR4      V P                  RR4      V P                  RR4      V P                  R	R4      V P                  R
R4      V P                  RR4      V P                  RR4      V P                  RR4      V P                  RR4      V P                  RR4      V P                  RR4      V P                  RR4      V P                  RR4      RVV34       VP                  4        V P                  R4       RV 2p\        P                  RV R24       RRRV/uuRRR4       V'       d    VP                  4        # #     # ; i  + '       g   i     M; i  \        P                   d[   pR\        T4       2p	\        P                  T	4       RRRRRRR R!R"R#/u Rp?T'       d    TP                  4        #     # ; i# Rp?i\         d[   pR$\        T4       2p	\        P                  T	4       RRRR%RR&R R!R"R#/u Rp?T'       d    TP                  4        #     # ; i# Rp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)'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_OpportunityNumberrB   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_ContactEmailrG   -r.   z creada exitosamentesuccessTopportunity_idz-Error de base de datos al crear oportunidad: Fmessagez,Error al guardar los datos de la oportunidadcodeDATABASE_ERROR
alert_typer   status_codei  z'Error inesperado al crear oportunidad: z(Error interno al procesar la oportunidadINTERNAL_ERROR)obtener_nombre_usuarior   r2   r   r   rJ   r   r   r   r   r8   r9   r   r   r   )
rP   rQ   rR   	user_namer   r   r   re   r!   r=   s
   &&&       r"   crear_actualizar_oportunidadrn   $  s    'w/IE0 DA!"XYYT[[]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4 .9 Tp 

 y TB << 	
CCF8L	YuE$'3
 	
( 

	   	
=c!fXF	YuA$'3
 	
 

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

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

	 s   'G EF>
G %F77F;>G		G K G J#&.H;J#K "H33H7;J#J#	.J7J#8K JJJ##K 0K K	K/K'&K/'K+)K/c                H    V ^8  d   QhR\         R\         R\        R\        /# )r&   re   quotation_type_idrQ   r'   )r   rS   r   )r)   s   "r"   r*   r*     s0     K K# K# KPS KX\ Kr+   c           
        \        V4      pRpRp \        4       pV'       g   \        R4      hV;_uu_ 4        VP                  4       pVP	                  VV VVVV34       VP                  4        V  RV 2p\        P                  RV R24       RRR	V/uuRRR4       V'       d    VP                  4        # #     # ; i  + '       g   i     M; i  \        P                   dY   pR
\        T4       2p	\        P                  T	4       RRRRRRRR/u Rp?T'       d    TP                  4        #     # ; i# Rp?i\         dY   pR\        T4       2p	\        P                  T	4       RRRRRRRR/u Rp?T'       d    TP                  4        #     # ; i# Rp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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-   rc   z	FormHead z creado exitosamenterd   Tform_idz*Error de base de datos al crear FormHead: Frf   z%Error al crear registro de formulariorg   rh   ri   r   z$Error inesperado al crear FormHead: z!Error interno al crear formulariork   )rl   r   r2   r   r   r   r   r   r   r8   r9   r   r   r   )
re   rp   rQ   rm   r   r   r   rr   r!   r=   s
   &&&       r"   crear_formulario_headrs     s    'w/IE D1!"XYYT[[]FNN5!#  KKM'(*;)<=GKK)G9,@AB47 TP 

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

	   
:3q6(C	Yu:$'	
 	
 

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

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

	 s   'C AC
C (B::B>C	C G C F"),D<F"G #D44D8<F"	F"
,F6F"7G FFF""G /G G	G.G&%G.&G*(G.c                R    V ^8  d   QhR\         R\        \        ,          R\        /# )r&   rr   	preguntasr'   )r   r   r   )r)   s   "r"   r*   r*     s*     a ac ad4j aT ar+   c                P   \        RV  24       \        R\        V4       24       \        V4       F  w  r#\        RV^,            RV 24       K  	  RpRp \        4       pV'       g   \	        R4      h^ pT;_uu_ 4        VP                  4       p\        V^R7       F  w  r\        V4      P                  ^4      p	\        R	V R
24       \        RV  24       \        RV	 24       \        RVR,           24       \        RVR,           24       \        RVR,           24       \        RV  RV	 24       VP                  VV V	VR,          VR,          VR,          34       V^,          p\        RV R24       K  	  VP                  4        \        P                  RV RV  24       RRRV/uuRRR4       V'       d    VP                  4        # #     # ; i  + '       g   i     M; i  \        P                   dg   p
R\        T
4       2p\        P                  T4       \        RT 24       RRRR R!R"R#R$/u Rp
?
T'       d    TP                  4        #     # ; i# Rp
?
i\          dg   p
R%\        T
4       2p\        P                  T4       \        R&T 24       RRRR'R!R(R#R$/u Rp
?
T'       d    TP                  4        #     # ; i# Rp
?
ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i))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 r0   z
        INSERT INTO Q_SpQ_FormsDetail (
            FormID,
            FormLine,
            Question,
            TypeQuestion,
            Answer
        ) VALUES (?, ?, ?, ?, ?)
    Nr-   )startu!   🔍 DEBUG - Insertando registro :z    FormID: z    FormLine: z    Question: preguntaz    TypeQuestion: tipoElementoz    Answer: 	respuestaz    Expected FormLineID: rc   u   ✅ DEBUG - Registro z insertado exitosamentezCreados z detalles para FormID rd   Trecords_createdz-Error de base de datos al crear FormDetails: u   ❌ DEBUG - Error SQL: Frf   z(Error al guardar detalles del formulariorg   rh   ri   r   z'Error inesperado al crear FormDetails: u   ❌ DEBUG - Error general: z!Error interno al guardar detallesrk   )r1   len	enumerater   r2   r   r   zfillr   r   r   r   r   r8   r9   r   r   )rr   ru   iry   r   r   registros_creadosr   index	form_liner!   r=   s   &&          r"   crear_formulario_detailsr     sI    
!'
+,	*3y>*:
;< +&qse2hZ89 ,E DD!"XYYT[[]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!#4; Tr 

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

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

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

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

	 s   )G/  D0G0
G/ GGG,	'G/ +L ,G/ /K:I%>K?L II!%K2K3:K-K.L ;KKKL &K8 8K=	L%LL%L!L%c          
      T    V ^8  d   QhR\         R\        R\        R\        R\        /# )r&   seller_user_idrr   re   rm   r'   )rS   r   r   )r)   s   "r"   r*   r*   A  s8     N N3 N Nc N^a Nfj Nr+   c           
        RpRp \        4       pV'       g   \        R4      hV;_uu_ 4        VP                  4       pVP                  VV VRVV34       VP                  R4       VP	                  4       ^ ,          pVP                  4        \        P                  RV RV 24       RR	R
V/uuRRR4       V'       d    VP                  4        # #     # ; i  + '       g   i     M; i  \        P                   dY   pR\        T4       2p	\        P                  T	4       RRRRRRRR/u Rp?T'       d    TP                  4        #     # ; i# Rp?i\         dY   pR\        T4       2p	\        P                  T	4       RRRRRRRR/u Rp?T'       d    TP                  4        #     # ; i# Rp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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 TaskIDzTarea z creada para FormID rd   Ttask_idz'Error de base de datos al crear tarea: Frf   u#   Error al crear tarea de cotizaciónrg   rh   ri   r   z!Error inesperado al crear tarea: zError interno al crear tareark   )r   r2   r   r   r   r   r   r   r   r8   r9   r   r   r   )
r   rr   re   rm   r   r   r   r   r!   r=   s
   &&&&      r"   crear_tarea_cotizacionr   A  s	   	E D4!"XYYT[[]FNN5#  NN89oo'*GKKMKK&	)=gYGH47# TV 

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

	   
7Ax@	Yu5$'	
 	
 

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

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

	 s   'C, B C-
C,  CCC)	$C, (G# )C, ,F:,E-F:.G# ;EEF:!F:",F5F:G# F--F15F::G# G G#	H-G>=H>H Hc                0    V ^8  d   QhR\         R\        /# r&   rQ   r'   )rS   r   )r)   s   "r"   r*   r*     s     6 6C 6C 6r+   c           	        RpRp \        4       pV'       g    RV  2V'       d    VP                  4        # # T;_uu_ 4        VP                  4       pVP                  W34       VP	                  4       pV'       dh   RP                  V^ ,          P                  4       4      pVP                  4       '       d   TMRV  2uuRRR4       V'       d    VP                  4        # # RV  2uuRRR4       V'       d    VP                  4        # #     # ; i    # ; i    # ; i  + '       g   i     Me; i  \         dU   p\        P                  RT  R\        T4       24       RT  2u Rp?T'       d    TP                  4        #     # ; i# Rp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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_ z#Error al obtener nombre de usuario r0   )r   r   r   r   r   joinsplitstripr   r   r7   r   )rQ   r   r   r   r   	full_namer!   s   &      r"   rl   rl     s   E  DgY'& 

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

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

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

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

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

	 s   D4 D
D4 A6D!8D!>
D4 D#D!'
D4 :DDDD!D1	,D4 0F< 1D4 4F?(F'F(F< 5FF
FF<  F2 2F7<	GGGGGc                0    V ^8  d   QhR\         R\        /# )r&   rp   r'   )r   bool)r)   s   "r"   r*   r*     s     3 3 3 3r+   c           	        RpRp \        4       pV'       g7   \        P                  RV  24        V'       d    VP                  4        R# R# T;_uu_ 4        VP	                  4       pVP                  W34       VP                  4       pV'       dT   \        V^ ,          4      p\        P                  RV  RV 24       TuuRRR4       V'       d    VP                  4        # # \        P                  RV  R24        RRR4       V'       d    VP                  4        R# R#     R# ; i    # ; i    R# ; i  + '       g   i     M; i  \        P                   dS   p\        P                  RT  R	\        T4       24        Rp?T'       d    TP                  4        R#     R# ; iR# Rp?i\         dS   p\        P                  R
T  R	\        T4       24        Rp?T'       d    TP                  4        R#     R# ; iR# Rp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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 TzQuotationType z - CreateTask: z no encontradoz)Error de BD al consultar CreateTask para r0   z.Error inesperado al consultar CreateTask para )r   r   r7   r   r   r   r   r   r   r8   r9   r   r   r   )rp   r   r   r   r   create_taskr!   s   &      r"   debe_crear_tarear     s$   E D NNNO`Nabc0 

 - T[[]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   *E D% 
E A)D<
E D-&D< E D4 %D*-D14D9<E	E H: E H$$F1H: F' 'F,1H>H?$H#H: 0H HHH: H0 0H5:	IIIIIc           	     H   RpRp \        4       pV'       g    V'       d    VP                  4        R# R# T;_uu_ 4        VP                  4       pVP                  W34       VP	                  4       pV'       d.   V^ ,          uuRRR4       V'       d    VP                  4        # #  RRR4       V'       d    VP                  4        R# R#     R# ; i    # ; i    R# ; i  + '       g   i     Mc; i  \
         dS   p\        P                  RT  R\        T4       24        Rp?T'       d    TP                  4        R#     R# ; iR# Rp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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 = ?
    Nz$Error al obtener TaskID para FormID r0   )	r   r   r   r   r   r   r   r7   r   )taskIDr   r   r   r   r!   s   &     r"   get_FormID_by_TaskIDr      sr   E D" 

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

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

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

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

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

	 s   C8 C 
C8  AC%
C8 C(C%)C8 :C CCC"%C5	0C8 4E> 5C8 8E$E'E> 4E EEE> "E4 4E9>	F!FF!FF!c                0    V ^8  d   QhR\         R\         /# )r&   tipo_formularior'   )r   )r)   s   "r"   r*   r*   -  s     8 8s 8s 8r+   c                V    RRRRRRRRR	R
RRRRRRRRRRRR/pVP                  V R4      # )z
Mapea el tipo de formulario al QuotationTypeID correspondiente

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

Returns:
    str: QuotationTypeID correspondiente
GeneralFormGralSolicVisFormSolicVis
PTTransNacFormPTTransNac	PTTransULFormPTTransULAireFormAireSistCritUPSFormSistCritUPSBessFormBessSolar	FormSolarEnergyCogeneration
FormEneCogImess	FormImess	ProyecEspFormProyecEsp)rJ   )r   mapeo_tiposs   & r"   obtener_quotation_type_idr   -  sW     	:N&_
(
l_K ???J77r+   c                0    V ^8  d   QhR\         R\         /# r   )rS   )r)   s   "r"   r*   r*   H  s     - -C -C -r+   c           	     n   RpRp \        4       pV'       g   T V'       d    VP                  4        # # T;_uu_ 4        VP                  4       pVP                  W34       VP	                  4       pV'       dF   V^ ,          '       d7   \        V^ ,          4      uuRRR4       V'       d    VP                  4        # # T uuRRR4       V'       d    VP                  4        # #     # ; i    # ; i    # ; i  + '       g   i     Mb; i  \         dR   p\        P                  RT  R\        T4       24       T u Rp?T'       d    TP                  4        #     # ; i# Rp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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 = ?
    Nz+Error al obtener SellerUserID para usuario r0   )
r   r   r   r   r   rS   r   r   r7   r   )rQ   r   r   r   r   r!   s   &     r"   obtener_seller_user_idr   H  s   E D" 

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

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

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

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

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

	 s   D C$
D A	C9C9
D ,C+>C9?
D C2$C(+C/2C69D		D F 	D E(%E#<E(=F 
EE#E((F 5F F	F4F,+F4,F0.F4c                <    V ^8  d   QhR\         R\        R\        /# )r&   rr   docs_idr'   )r   rS   r4   )r)   s   "r"   r*   r*   w  s&     A AC A# A$ Ar+   c                h   RpRp \        4       pV'       g   \        R4      hT;_uu_ 4        VP                  4       pVP                  W!V 34       VP                  pVP                  4        V^ 8  dD   \        P                  RV  RV 24       RR/uuRRR4       V'       d    VP                  4        # # \        P                  RV  R	24       RR
RR/uuRRR4       V'       d    VP                  4        # #     # ; i    # ; i  + '       g   i     M; i  \        P                   dW   pR\        T4       2p\        P                  T4       RR
RRRR/u Rp?T'       d    TP                  4        #     # ; i# Rp?i\         dW   pR\        T4       2p\        P                  T4       RR
RRRR/u Rp?T'       d    TP                  4        #     # ; i# Rp?ii ; i T'       d    TP                  4        R#     R# ; iR#   T'       d    TP                  4        i     i ; ii ; i)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-   zFormulario z actualizado con DocsID rd   Tu   No se encontró formulario z para actualizarFrf   z(Formulario no encontrado para actualizarz1Error de base de datos al actualizar formulario: z-Error al actualizar formulario con documentosrg   rh   z+Error inesperado al actualizar formulario: z&Error interno al actualizar formulariork   )r   r2   r   r   rowcountr   r   r   r   r7   r8   r9   r   r   r   )rr   r   r   r   r   rows_affectedr!   r=   s   &&      r"   actualizar_formulario_con_docsr   w  s)   E D-!"XYYT[[]FNN5G"45"OOMKKMq k'2J7)TU!4( TH 

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

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

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

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

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

	 s   'D A%D
D %C:7D
D (D:C>DD	D H D G%0*FG%H (E99E=G%G%*G 9G%:H GG G%%H 2H H		H1H)(H1)H-+H1)r8   loggingr   typingr   r   r   r   	getLoggerr   configr	   r
   Consultas_SQL.conexionr   r#   r>   rN   rn   rs   r   r   rl   r   r   r   r   r    r+   r"   <module>r      s       . . 
		8	9 * 1OfgTRhjZKZaFN`6p3n+Z86-^Ar+   