+
    i!                     *    ^ RI t ^ RIt ! R R4      tR# )    Nc                   R   a  ] tR t^
t o RtR tR tR tRR ltR t	R t
R	 tR
tV tR# )
CRMManageruj   
Clase que gestiona la conexión y las operaciones con la API de
Microsoft Dynamics 365 Business Central.
c                z   VP                  R4      V n        VP                  R4      V n        VP                  R4      V n        VP                  R4      V n        VP                  R4      V n        RV P                   R2V n        RV P                   R	V P                   R
2V n        RV n        ^ V n	        RV n
        R# )u   
Inicializa el gestor del CRM con un objeto de configuración de Flask.

Args:
    config: El objeto app.config (que se accede como diccionario).
BC_TENANT_IDBC_CLIENT_IDBC_CLIENT_SECRETBC_ENV_NAMEBC_COMPANY_NAMEz"https://login.microsoftonline.com/z/oauth2/v2.0/token.https://api.businesscentral.dynamics.com/v2.0//z	/api/v2.0N)get	tenant_id	client_idclient_secretenv_namecompany_name	token_urlapi_base_urlaccess_tokentoken_expires_atcompany_guid)selfconfigs   &&aC:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\App\Utilities_module\CRMManagement.py__init__CRMManager.__init__   s     $ZZ7DN#ZZ7DN!',>!?D"JJ}5DM &

+< =D  B$..AQQcdDN"PQUQ_Q_P``abfboboappy zD !%D$%D! $D    c                J   V P                   '       d.   \        P                  ! 4       V P                  ^<,
          8  d   R# RR/pRRRV P                  RV P                  RR	/p \
        P                  ! V P                  WR
7      pVP                  4        VP                  4       pVR,          V n         \        P                  ! 4       VR,          ,           V n        \        R4       R#   \
        P                  P                   d   p\        RT 24       RT n         h Rp?ii ; i)ur   
Obtiene un token de acceso. Si el token existente es válido, lo reutiliza.
De lo contrario, solicita uno nuevo.
NContent-Typez!application/x-www-form-urlencoded
grant_typeclient_credentialsr   r   scopez1https://api.businesscentral.dynamics.com/.default)headersdatar   
expires_inu3   ✅ Token de acceso obtenido/renovado exitosamente.u   ❌ Error al obtener el token: )r   timer   r   r   requestspostr   raise_for_statusjsonprint
exceptionsRequestException)r   r#   payloadresponser$   es   &     r   
_get_tokenCRMManager._get_token&   s    
 t/D/Dr/I!I!#FG.T//H	
	}}T^^WSH%%'==?D $^ 4D$(IIK$|2D$DD!GH""33 	3A378 $D	s   #BC( (D"DD"c                   V P                   '       d   R# V P                  4        V P                   R2pRRV P                   2/p \        P
                  ! WR7      pVP                  4        VP                  4       P                  R. 4      pV Fa  pVP                  R4      V P                  8X  g   K%  VP                  R4      V n         \        R	V P                   R
V P                    24        R# 	  \        RV P                   R24      h  \        P                  P                   d   p\        RT 24       h Rp?ii ; i)uD   
Obtiene y almacena en caché el GUID de la compañía configurada.
Nz
/companiesAuthorizationBearer )r#   valuenameidu   ✅ GUID para 'z' encontrado: u-   No se encontró la compañía con el nombre ''u/   ❌ Error al obtener el GUID de la compañía: )r   r1   r   r   r'   r   r)   r*   r   r+   	Exceptionr,   r-   )r   urlr#   r/   	companiescompanyr0   s   &      r   _get_company_guidCRMManager._get_company_guidD   s%    ""#:."gd.?.?-@$AB	||C9H%%' ++GR8I$;;v&$*;*;;(/D(9D%OD,=,=+>nTM^M^L_`a	 % KDL]L]K^^_`aa""33 	CA3GH	s%   A)D 4<D 2D E ,D;;E Nc           
     |   V P                  4        V P                  4        RpRV P                   RV P                   RV RV P                   RV 2
pRRV P
                   2R	R
/p \        P                  ! VP                  4       WVVR7      pVP                  4        VP                  '       d   VP                  4       # RRRVP                  /#   \        P                  P                   dN   p\        RT RT 24       \        RTP                   '       d   TP                   P"                  MR 24       h Rp?ii ; i)uE   
Método genérico para realizar llamadas a los endpoints de la API.
zIGSA/integration/v1.0r   r   z/api/z/companies(z)/r4   r5   r   zapplication/json)r#   r*   statussuccesscodeu   ❌ Error en la llamada API a 'z': zDetalle del error: zSin respuestaN)r1   r>   r   r   r   r   r'   requestupperr)   contentr*   status_coder,   r-   r+   r/   text)	r   methodendpointr.   api_group_pathr;   r#   r/   r0   s	   &&&&     r   _make_api_requestCRMManager._make_api_request`   s1    	  1??OqQUQ^Q^P_N#;t/@/@.AH:O wt'8'8&9:.

	''SZ[H%%'&.&6&6&68==?oXyRXZbZnZn<oo""33 	3H:SDE'1:::

?'[\]	s    &AC ?C D;.AD66D;c                <    \        R4       V P                  RR4      # )z6
Obtiene la lista de todas las oportunidades del CRM.
u+   ℹ️ Obteniendo lista de oportunidades...GETopportunitiesr+   rL   )r   s   &r   get_opportunitiesCRMManager.get_opportunities~   s      	;<%%e_==r   c                @    \        R4       V P                  RRVR7      # )uB   
Envía los datos de una cotización al CRM para su importación.
u%   ℹ️ Enviando cotización al CRM...POSTquoteImports)r.   rQ   )r   
quote_datas   &&r   
send_quoteCRMManager.send_quote   s%     	56%%fnj%QQr   c                0   RV R2pV P                  RV4      pVP                  R. 4      pV'       g   \        RV R24      hV^ ,          pVP                  R4      p/ pV'       dM   RV R2pV P                  RV4      p	V	P                  R. 4      p
V
'       d   V
^ ,          pM\        R	V R
24       M\        RV R24       VP                  R4      p/ pV'       dM   RV R2pV P                  RV4      pVP                  R. 4      pV'       d   V^ ,          pM\        RV R
24       M\        RV R24       RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      RVP                  R4      R VP                  R 4      /pV# )!up   
Obtiene y consolida el contexto completo (Oportunidad, Contacto y Vendedor) 
para una cotización específica.
zopportunities?$filter=No eq 'r9   rO   r6   zOportunidad 'z' no encontrada en el CRM.	ContactNozcontactsImports?$filter=No eq 'uI   ⚠️ Aviso: No se encontró la información detallada del Contacto No. .u   ⚠️ Aviso: La oportunidad z  no tiene un ContactNo asignado.SalespersonCodez/salespersonImports?$filter=SalespersonCode eq 'uA   ⚠️ Aviso: No se encontró la información del Vendedor Cód. z& no tiene un SalespersonCode asignado.NoContactNameNameContactTypeTypeSalespersonNameContactEMailEMailStatusAddressColonyPhoneCityCountyPriorityPostCode)rL   r   
ValueErrorr+   )r   opportunity_noopp_endpointopportunities_dataopportunity_listopportunity
contact_nocontactcontact_endpointcontacts_datacontact_listsalesperson_codesalespersonsales_endpoint
sales_data
sales_listconsolidated_contexts   &&               r   get_opportunity_context"CRMManager.get_opportunity_context   s'    7~6FaH!33E<H-11'2>}^,<<VWXX&q) !__[1
!@AN 225:JKM(,,Wb9L&q/ablammnop1.1AAabc '??+<=NO_N``abN//~FJ#4J(mYZjYkklmn1.1AAghi
 +//$'7;;v.7;;v.{v6GKK0kooh/w{{9-gkk(+W[[)GKK'gkk(+
3J/ 
  $#r   )
r   r   r   r   r   r   r   r   r   r   )N)__name__
__module____qualname____firstlineno____doc__r   r1   r>   rL   rR   rX   r   __static_attributes____classdictcell__)__classdict__s   @r   r   r   
   s5     %.<8<>R@$ @$r   r   )r'   r&   r    r   r   <module>r      s     B$ B$r   