
    f6ilN                         d Z ddlZddlmZmZmZmZ ddlmZm	Z	 ddl
m
Z
 ddlmZ  G d de      Z G d	 d
e      Z G d de      Z G d de      Zdedeeef   defdZy)uF   
Сервисы для интеграции с CRM системами
    N)DictListAnyOptional)ABCabstractmethod)datetime)get_settingsc                      e Zd ZdZdeeef   fdZede	fd       Z
eddededeeeef      fd       Zed	edeeef   fd
       Zedeeef   deeef   fd       Zed	edeeef   deeef   fd       Zdeeef   deeef   fdZd Zy)BaseCRMClientu5   Базовый класс для CRM клиентовconfigc                 H    || _         t        j                  d      | _        y )Ng      >@)timeout)r   httpxAsyncClientclient)selfr   s     7/var/www/notifications/app/services/crm_integrations.py__init__zBaseCRMClient.__init__   s    ''5    returnc                    K   yw)u0   Проверить подключение к CRMN r   s    r   test_connectionzBaseCRMClient.test_connection         	   limitoffsetc                    K   yw)u9   Получить список контактов из CRMNr   )r   r   r   s      r   get_contactszBaseCRMClient.get_contacts   r   r   
contact_idc                    K   yw)u0   Получить один контакт по IDNr   )r   r"   s     r   get_contactzBaseCRMClient.get_contact   r   r   contact_datac                    K   yw)u$   Создать контакт в CRMNr   r   r%   s     r   create_contactzBaseCRMClient.create_contact!   r   r   c                    K   yw)u&   Обновить контакт в CRMNr   r   r"   r%   s      r   update_contactzBaseCRMClient.update_contact&   r   r   crm_contactc                     |j                  d      |j                  d      |j                  dg       |j                  d      | j                  j                  |ddS )u\   Нормализовать контакт из CRM в формат нашей системыemailphonetagsid)crm_idcrm_typecrm_data)r.   r/   r0   meta)get	__class____name__)r   r,   s     r   normalize_contactzBaseCRMClient.normalize_contact+   sU     !__W- __W-OOFB/%//$/ NN33'		
 		
r   c                 T   K   | j                   j                          d{    y7 w)u    Закрыть HTTP клиентN)r   acloser   s    r   closezBaseCRMClient.close8   s     kk  """s   (&(Nd   r   )r8   
__module____qualname____doc__r   strr   r   r   boolr   intr   r!   r$   r(   r+   r9   r<   r   r   r   r   r      s/   ?6tCH~ 6 t    3 tDQTVYQYNG[   C DcN   c3h DcN   s $sCx. UYZ]_bZbUc  
T#s(^ 
S#X 
#r   r   c            
            e Zd ZdZdeeef   f fdZdeeef   fdZde	fdZ
dee   fdZdded	edeeeef      fd
Zdedeeef   fdZdeeef   deeef   fdZdedeeef   deeef   fdZ xZS )AmoCRMClientu*   Клиент для работы с AmoCRMr   c                 N   t         |   |       |j                  dd      j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        | j
                  st        d      y )	Napi_url /access_token	client_idclient_secretredirect_uriS   Access token не найден. Интеграция не авторизована.)
superr   r6   rstriprH   rK   rL   rM   rN   
ValueErrorr   r   r7   s     r   r   zAmoCRMClient.__init__@   s     zz)R077<"JJ~6K0#ZZ8"JJ~6  rss !r   r   c                 &    d| j                    ddS )u;   Получить заголовки для запросовzBearer zapplication/json)AuthorizationzContent-Type)rK   r   s    r   _get_headerszAmoCRMClient._get_headersK   s"      't'8'8&9:.
 	
r   c                    K   	 | j                   j                  | j                   d| j                                d{   }|j                  dk(  S 7 # t
        $ r}t        d|        Y d}~yd}~ww xY ww)u3   Проверить подключение к AmoCRMz/api/v4/accountheadersN   zAmoCRM connection error: F)r   r6   rH   rV   status_code	Exceptionprintr   responsees      r   r   zAmoCRMClient.test_connectionR   s}     	![[__<<.0))+ -  H ''3..	
  	-aS12	s?   A9;A A A A9A 	A6A1,A91A66A9c           	        K   | j                   j                  d      }|sy	 | j                  j                  | j                   d| j
                  | j                  d|| j                  d       d{   }|j                  dk(  r2|j                         }|j                  d      | _
        | j                  S 	 y7 G# t        $ r}t        d|        Y d}~yd}~ww xY ww)	u6   Обновить access token через refresh tokenrefresh_tokenNz/oauth2/access_token)rL   rM   
grant_typerb   rN   )jsonrZ   rK   zToken refresh error: )r   r6   r   postrH   rL   rM   rN   r[   rd   rK   r\   r]   r   rb   r_   datar`   s        r   refresh_access_tokenz!AmoCRMClient.refresh_access_token^   s     8	/![[--<<. 45!%%)%7%7"1%2$($5$5 . 	 	H ##s*}}$(HH^$<!((( + %	  	/)!-..	/sH   C!AB= 3B;4AB= 8C!:C!;B= =	CCC!CC!r   r   c                   K   	 | j                   j                  | j                   d| j                         |||z  dz   d       d{   }|j                  dk(  r2| j                          d{   r| j                  ||       d{   S |j                  dk(  rs|j                         }|j                  di       j                  d	g       }g }|D ]7  }|j                  d
g       }d}	d}
|D ]~  }|j                  d      dk(  r*|j                  dg       }|s,|d   j                  d      }	A|j                  d      dk(  sV|j                  dg       }|sk|d   j                  d      }
 |j                  t        |j                  d            |j                  d      |	|
|j                  di       j                  dg       D cg c]  }|j                  d       c}|j                  d      |j                  d      d       : |S 	 g S 7 7 7 c c}w # t        $ r}t        d|         d}~ww xY ww)u<   Получить список контактов из AmoCRM/api/v4/contacts   )r   page)rY   paramsNi  rZ   	_embeddedcontactscustom_fields_values
field_codeEMAILvaluesr   valuePHONEr1   namer0   
created_at
updated_atr1   rv   r.   r/   r0   rw   rx   z Error fetching AmoCRM contacts: )r   r6   rH   rV   r[   rh   r!   rd   appendrB   r\   r]   )r   r   r   r_   rg   ro   
normalizedcontactcustom_fieldsr.   r/   fieldrs   tagr`   s                  r   r!   zAmoCRMClient.get_contactsy   s=    .	![[__<<. 01))+!&%!0CD -  H ##s*22444!%!2!25&!AAA##s*}}88K488RH  
' G$+KK0F$KM E E!. ? 99\2g=%*YYx%<F%(.q	g(>"YY|4?%*YYx%<F%(.q	g(>? %%!'++d"34 'F 3!&!&<CKKUW<X<\<\]ceg<h iS i&-kk,&?&-kk,&?' 2 "!? +H 	_ 5A8 !j  	4QC89	s   IAH# 	H
&H# 0H1H# 
HH# IBH# )H# H# A0H# H$-H# IIH# H# H# H# #	I ,H;;I  Ir"   c                   K   	 | j                   j                  | j                   d| | j                                d{   }|j                  dk(  r|j                         S 	 i S 7 &# t        $ r}t        d|         d}~ww xY ww)u4   Получить один контакт из AmoCRM/api/v4/contacts/rX   NrZ   zError fetching AmoCRM contact: )r   r6   rH   rV   r[   rd   r\   r]   r   r"   r_   r`   s       r   r$   zAmoCRMClient.get_contact   s     
	![[__<<. 1*>))+ -  H
 ##s*}}& + 	  	3A378	s@   B
=A* A("A* $B
&B
(A* *	B3BBB
r%   c                   K   |j                  dd      g dg}|j                  d      r!|d   d   j                  d|d   dd	gd
       |j                  d      r!|d   d   j                  d|d   dd	gd
       	 | j                  j                  | j                   d| j                         |       d{   }|j                  dv r|j                         S 	 i S 7 %# t        $ r}t        d|         d}~ww xY ww)u'   Создать контакт в AmoCRMrv   New Contact)rv   rp   r.   r   rp   rr   WORK)rt   	enum_code)rq   rs   r/   ru   rj   rY   rd   N)rZ      zError creating AmoCRM contact: )
r6   rz   r   re   rH   rV   r[   rd   r\   r]   )r   r%   amocrm_datar_   r`   s        r   r(   zAmoCRMClient.create_contact   s9    
 %((?(*
 G$N1299%%1'%:PQ; 
 G$N1299%%1'%:PQ; 
	![[--<<. 01))+  .  H ##z1}}& 2 	  	3A378	sB   A;D><C" :C ;!C" DD C" "	C?+C::C??Dc                   K   	 | j                   j                  | j                   d| | j                         |       d{   }|j                  dk(  r|j                         S 	 i S 7 &# t        $ r}t        d|         d}~ww xY ww)u)   Обновить контакт в AmoCRMr   r   NrZ   zError updating AmoCRM contact: )r   patchrH   rV   r[   rd   r\   r]   r   r"   r%   r_   r`   s        r   r+   zAmoCRMClient.update_contact   s     	![[..<<. 1*>))+! /  H ##s*}}& + 	  	3A378	s@   B>A+ A)"A+ %B'B)A+ +	B4BBBr=   )r8   r?   r@   rA   r   rB   r   r   rV   rC   r   r   rh   rD   r   r!   r$   r(   r+   __classcell__r7   s   @r   rF   rF   =   s    4	ttCH~ 	t
d38n 

t 
HSM 62 23 2tDQTVYQYNG[ 2hC DcN  #c3h #DcN #Js $sCx. UYZ]_bZbUc r   rF   c            
            e Zd ZdZdeeef   f fdZdedefdZde	fdZ
dded	edeeeef      fd
Zdedeeef   fdZdeeef   deeef   fdZdedeeef   deeef   fdZdee   fdZ xZS )Bitrix24ClientuY   Клиент для работы с Bitrix24 через единое приложениеr   c                     t         |   |       |j                  dd      | _        |j                  d      | _        t               | _        | j                  st        d      y )NdomainrI   rK   rO   )rP   r   r6   r   rK   r
   settingsrR   rS   s     r   r   zBitrix24Client.__init__   sV     jj2."JJ~6$  rss !r   methodr   c                 &    d| j                    d| S )u,   Получить URL для API методаzhttps://z/rest/)r   )r   r   s     r   _get_urlzBitrix24Client._get_url   s    $++fVH55r   c                    K   	 | j                   j                  | j                  d      d| j                  i       d{   }|j	                         }d|v S 7 # t
        $ r}t        d|        Y d}~yd}~ww xY ww)u5   Проверить подключение к Bitrix24zuser.currentauthrm   NresultzBitrix24 connection error: F)r   r6   r   rK   rd   r\   r]   )r   r_   rg   r`   s       r   r   zBitrix24Client.test_connection  s     		![[__n- 1 12 -  H ==?Dt##  	/s34	s?   A>;A A A A>A 	A;#A61A>6A;;A>r   r   c                 \  K   	 | j                   j                  | j                  d      | j                  |i g dd       d{   }|j                  dk(  r-|j                         }|j                  dg       }g }|D ]  }d}d}	|j                  d      r+|d   }
|
r$t        |
t              r|
d	   j                  d
      }|j                  d      r+|d   }|r$t        |t              r|d	   j                  d
      }	|j                  t        |j                  d            |j                  dd       d|j                  dd       j                         ||	g |j                  d      |j                  d      d        |S 	 g S 7 E# t        $ r}t        d|         d}~ww xY ww)u>   Получить список контактов из Bitrix24zcrm.contact.list)IDNAME	LAST_NAMErr   ru   )r   startfilterselectr   NrZ   r   rr   r   VALUEru   r   r   rI    r   DATE_CREATEDATE_MODIFYry   z"Error fetching Bitrix24 contacts: )r   r6   r   rK   r[   rd   
isinstancelistrz   rB   stripr\   r]   )r   r   r   r_   rg   ro   r{   r|   r.   r/   emailsphonesr`   s                r   r!   zBitrix24Client.get_contacts  s    -	![[__01 --# K	 -  H ##s*}}88Hb1  
' G E E {{7+!(!1!j&>$*1IMM'$:E{{7+!(!1!j&>$*1IMM'$:E%%!'++d"34#*;;vr#:";1W[[VX=Y<Z [ a a c!&!& "&-kk-&@&-kk-&@' 2 "!? +H 	]T  	6qc:;	sB   F,A F F	E F F,F,	F 	F)F$$F))F,r"   c                 :  K   	 | j                   j                  | j                  d      | j                  |d       d{   }|j                  dk(  r"|j                         }|j                  di       S 	 i S 7 8# t        $ r}t        d|         d}~ww xY ww)u6   Получить один контакт из Bitrix24zcrm.contact.getr   r1   r   NrZ   r   z!Error fetching Bitrix24 contact: )r   r6   r   rK   r[   rd   r\   r]   )r   r"   r_   rg   r`   s        r   r$   zBitrix24Client.get_contactD  s     	![[__/0 $ 1 1D -  H
 ##s*}}xx"-- + 	  	5aS9:	s@   B<A;  A94A; 5B7B9A; ;	BBBBr%   c                   K   d|j                  dd      i}|j                  d      r|d   ddg|d<   |j                  d      r|d   ddg|d	<   	 | j                  j                  | j                  d
      d| j                  id|i       d{   }|j
                  dk(  r|j                         S 	 i S 7 &# t        $ r}t        d|         d}~ww xY ww)u)   Создать контакт в Bitrix24r   rv   r   r.   r   )r   
VALUE_TYPErr   r/   ru   zcrm.contact.addr   fieldsrm   rd   NrZ   z!Error creating Bitrix24 contact: )	r6   r   re   r   rK   r[   rd   r\   r]   )r   r%   r   r_   r`   s        r   r(   zBitrix24Client.create_contactU  s     L$$V];
 G$)5g)>fUVF7OG$)5g)>fUVF7O	![[--/0 1 12' .  H ##s*}}& + 	  	5aS9:	sB   AC>B9 B7"B9 3C5C7B9 9	CCCCc                   K   	 | j                   j                  | j                  d      | j                  |dd|i       d{   }|j                  dk(  r|j                         S 	 i S 7 &# t        $ r}t        d|         d}~ww xY ww)u+   Обновить контакт в Bitrix24zcrm.contact.updater   r   r   NrZ   z!Error updating Bitrix24 contact: )r   re   r   rK   r[   rd   r\   r]   r   s        r   r+   zBitrix24Client.update_contactp  s     	![[--23 $ 1 1D- .  H ##s*}}& + 	  	5aS9:	s@   B?A, A*"A, &B(B*A, ,	B	5BB		Bc                 .  K   | j                   j                  d      }|sy| j                  j                  r| j                  j                  st        d       y	 | j                  j                  dd| j                  j                  | j                  j                  |d       d{   }|j                  dk(  r2|j                         }|j                  d      | _
        | j                  S 	 y7 G# t        $ r}t        d	|        Y d}~yd}~ww xY ww)
uF   Обновить access token через refresh token для Bitrix24rb   NuX   BITRIX_CLIENT_ID или BITRIX_CLIENT_SECRET не настроены на сервереz%https://oauth.bitrix.info/oauth/token)rc   rL   rM   rb   )rg   rZ   rK   zBitrix24 token refresh error: )r   r6   r   BITRIX_CLIENT_IDBITRIX_CLIENT_SECRETr]   r   re   r[   rd   rK   r\   rf   s        r   rh   z#Bitrix24Client.refresh_access_token  s     8}}--T]]5W5Wlm	8![[--7"1!%!?!?%)]]%G%G%2	 .  H ##s*}}$(HH^$<!((( + #  	821#677	8sJ   ADAC1 'C/(AC1 ,D.D/C1 1	D:DDDD)2   r   )r8   r?   r@   rA   r   rB   r   r   r   rC   r   rD   r   r!   r$   r(   r+   r   rh   r   r   s   @r   r   r      s    cttCH~ t6s 6s 6t 1 1# 1d4PSUXPX>FZ 1fC DcN "c3h DcN 6s $sCx. UYZ]_bZbUc "HSM r   r   c            
            e Zd ZdZdeeef   f fdZdefdZ	dde
de
deeeef      fdZd	edeeef   fd
Zdeeef   deeef   fdZd	edeeef   deeef   fdZ xZS )OneC1Clientu&   Клиент для работы с 1Cr   c                    t         |   |       |j                  dd      j                  d      | _        |j                  d      | _        |j                  d      | _        | j
                  | j                  f| _        y )NrH   rI   rJ   usernamepassword)rP   r   r6   rQ   rH   r   r   r   rS   s     r   r   zOneC1Client.__init__  sa     zz)R077<

:.

:.]]DMM2	r   r   c                    K   	 | j                   j                  | j                   d| j                  ddi       d{   }|j                  dk(  S 7 # t
        $ r}t        d|        Y d}~yd}~ww xY ww)	u/   Проверить подключение к 1C4   /odata/standard.odata/Catalog_Контрагенты$toprk   r   rm   NrZ   z1C connection error: F)r   r6   rH   r   r[   r\   r]   r^   s      r   r   zOneC1Client.test_connection  s     		![[__<<. TUYY{ -  H
 ''3..  	)!-.	s>   A8:A AA A8A 	A5A0+A80A55A8r   r   c                 6  K   	 | j                   j                  | j                   d| j                  ||dd       d{   }|j                  dk(  r|j                         }|j                  dg       }g }|D ]u  }|j                  |j                  d      |j                  d	      |j                  d
      |j                  d      g |j                  d      |j                  d      d       w |S 	 g S 7 # t        $ r}t        d|         d}~ww xY ww)u8   Получить список контактов из 1Cr   u6   Ref_Key,Description,ИНН,КПП,Email,Телефон)r   z$skipz$selectr   NrZ   rt   Ref_KeyDescriptionEmailu   Телефонu   ИННu   КПП)r1   rv   r.   r/   r0   innkppzError fetching 1C contacts: )	r   r6   rH   r   r[   rd   rz   r\   r]   )	r   r   r   r_   rg   ro   r{   r|   r`   s	            r   r!   zOneC1Client.get_contacts  s)    	![[__<<. TUYY!#W -  H ##s*}}88GR0  
' 	G%%%kk)4 'M :!(W!5!(-=!> "&{{84&{{84' 	 "!# +, 	A8  	045	sA   D<C9  C7B2C9 3D5D7C9 9	DDDDr"   c                   K   	 | j                   j                  | j                   d| d| j                         d{   }|j                  dk(  r|j                         S 	 i S 7 &# t        $ r}t        d|         d}~ww xY ww)u0   Получить один контакт из 1Cu:   /odata/standard.odata/Catalog_Контрагенты(guid'z'))r   NrZ   zError fetching 1C contact: )r   r6   rH   r   r[   rd   r\   r]   r   s       r   r$   zOneC1Client.get_contact  s     
	![[__<<. Z[eZffhiYY -  H
 ##s*}}& + 	  	/s34	s>   B:A' A%"A' !B#B%A' '	B0A??BBr%   c                     K   t        d      w)u#   Создать контакт в 1CuE   Создание контактов в 1C не реализованоNotImplementedErrorr'   s     r   r(   zOneC1Client.create_contact  s      ""ijj   c                     K   t        d      w)u%   Обновить контакт в 1CuI   Обновление контактов в 1C не реализованоr   r*   s      r   r+   zOneC1Client.update_contact  s      ""mnnr   r=   )r8   r?   r@   rA   r   rB   r   r   rC   r   rD   r   r!   r$   r(   r+   r   r   s   @r   r   r     s    03tCH~ 3t # #3 #tDQTVYQYNG[ #JC DcN  kc3h kDcN kos o$sCx. oUYZ]_bZbUc or   r   integration_typer   r   c                 x    t         t        t        d}|j                  |       }|st	        d|         ||      S )u9   Фабрика для создания CRM клиента)amocrmbitrix241cu-   Неподдерживаемый тип CRM: )rF   r   r   r6   rR   )r   r   clientsclient_classs       r   get_crm_clientr     sH     "G ;;/0LHIYHZ[\\r   )rA   r   typingr   r   r   r   abcr   r   r	   app.core.configr
   r   rF   r   r   rB   r   r   r   r   <module>r      s|     , , #  (/#C /#dt= tni] iXVo- Vor S  $sCx.  ]  r   