
    [d^i Q                        d Z ddlmZmZmZmZ ddlmZ ddlm	Z	 ddl
mZmZ ddlmZmZ ddlmZ ddlmZ dd	lmZmZmZmZmZmZmZmZ dd
lmZ ddlZddlZ eddg      Z  ejB                  e"      Z# G d de      Z$d.dede%dedz  de&fdZ'd/dede%dedz  de&dz  de&f
dZ(de&de&de&dz  fdZ)de&de&de&de&dz  fdZ*de&defdZ+	 	 	 	 	 d0dede%de&dz  d e&dz  d!e&dz  d"e&dz  d#e&dz  defd$Z,e j[                  d%       ee      fd&edefd'       Z.e j[                  d(       ee      fd&edefd)       Z/e j[                  d*       ee      fd&edefd+       Z0e jc                  d,      d-        Z2y)1uL   
Webhook обработчики для событий из CRM систем
    )	APIRouterDependsHTTPExceptionRequest)Session)and_)DictAny)datetime	timedelta)	BaseModel)get_db)UserCustomerIntegrationUserIndustryTemplateIndustryTemplateScheduledNotificationCustomFieldTenantSettings)decrypt_tokenNz/crm-webhookscrm-webhooks)prefixtagsc                   N    e Zd ZU dZeed<   eeef   ed<   dZeeef   dz  ed<   y)Bitrix24WebhookDatau"   Данные webhook от Bitrix24eventdataNauth)	__name__
__module____qualname____doc__str__annotations__r	   r
   r        G/Users/talgatiskakov/sites/serviceNotifications/app/api/crm_webhooks.pyr   r      s/    ,J
sCx."&D$sCx.4
&r'   r   db	tenant_idintegrationreturnc           	         | j                  t              j                  t        t        j                  |k(  t        j
                  dk(  t        j                  j                  d      z              j                         }| j                  t              j                  t        j                  |k(        j                         }|ru|j                  dk(  rf	 |j                  xs i }|j                  d      }|j                  d      xs |j                  d      }|r|rt        |      }t        ||      }	|	r|	S y
y
# t        $ r t         j#                  dd	       Y y
w xY w)uK   Получить адрес клиники из настроек или CRMclinic_addressu   %адрес%клиник%bitrix24access_token_encapi_urldomainz,Failed to fetch clinic address from Bitrix24Texc_infou   Адрес не указан)queryr   filterr   r*   namelabelilikefirstr   typeconfiggetr   get_bitrix24_company_address	Exceptionloggerwarning)
r)   r*   r+   clinic_fieldtenant_settingsr<   r0   r1   access_tokenaddresss
             r(   get_clinic_addressrF       s?    88K(//!!Y.!11k6G6G6M6MNi6jk	

 eg  hh~.55  I-eg 
 {'':5	Z ''-2F%zz*<=jj+Cvzz(/CGG,-=>6wM"N
 *	  	ZNNITXNY *		Zs   A#D: : EEappointment_idc           
      b   | j                  t              j                  t        t        j                  |k(  t        j
                  dk(  t        j                  j                  d      t        j                  j                  d      z  z              j                         }|ri|rg	 |j                  xs i }|j                  d      }|j                  d      xs |j                  d      }|r|rt        |      }t        |||      }	|	r|	S y
y
# t        $ r t        j                  dd	       Y y
w xY w)uG   Получить имя доктора из настроек или CRMdoctor_nameu   %доктор%u
   %врач%r0   r1   r2   z)Failed to fetch doctor name from Bitrix24Tr3   u   Доктор)r5   r   r6   r   r*   r7   r8   r9   r:   r<   r=   r   get_bitrix24_doctor_namer?   r@   rA   )
r)   r*   r+   rG   doctor_fieldr<   r0   r1   rD   rI   s
             r(   get_doctor_namerL   H   s)    88K(//!!Y..;3D3D3J3JK[3\_j_p_p_v_v  xD  `E  4E  F	

 eg  ~	W ''-2F%zz*<=jj+Cvzz(/CGG,-=>6wn]&&
 	  	WNNFQUNV 		Ws   $A$D  D.-D.r1   rD   c                    	 | j                  d       d}ddlm}  |||dddgdd	
      }|j                  dk(  r^|j	                         }|j                  d      r=t        |d         dkD  r,|d   d   }|j                  d      xs |j                  d      S y# t        $ r t        j                  dd       Y yw xY w)u^   Получить адрес компании из Bitrix24 (синхронная версия)/z/rest/crm.company.list.jsonr   )http_getYADDRESSTITLE)r   zfilter[ACTIVE]zselect[]      $@paramstimeout   resultNz&Failed to get Bitrix24 company addressTr3   )
rstripapp.utils.httprO   status_codejsonr=   lenr?   r@   rA   )r1   rD   rest_urlrO   responser   companys          r(   r>   r>   k   s    nnS)**EF+(CiY`Mab
 3&==?Dxx!c$x.&9A&=x.+{{9-EW1EE ?$Os   BB  B>=B>deal_idc                    	 | j                  d       d}t        j                  |||dd      }|j                  dk(  r{|j	                         }|j                  d      rZ|d   }|j                         D ]B  \  }}d|j                         v sd	t        |      j                         v s4|s7t        |      c S  y
# t        $ r Y y
w xY w)uh   Получить имя доктора из сделки в Bitrix24 (синхронная версия)rN   z/rest/crm.deal.get.json)r   idrS   rT   rW   rX   DOCTORu   ВРАЧN)	rY   requestsr=   r[   r\   itemsupperr$   r?   )	r1   rD   ra   r^   r_   r   dealkeyvalues	            r(   rJ   rJ      s    nnS)**AB<<$ 
 3&==?Dxx!H~ #'**, .JC399;.*E
@P@P@R2R #&u:-.
  s$   B'B< *B< -B< :B< <	CCdate_strc                     	 t        j                  | j                  dd            S #  t        j                         cY S xY w)u%   Парсинг даты из Bitrix24+03:00 )r   fromisoformatreplaceutcnow)rk   s    r(   parse_bitrix_daterr      s9    !%%h&6&6x&DEE!  s   $' ?phoneemailr7   
tg_chat_idexternal_idc           	         |ro| j                  t              j                  t        t        j                  |k(  t        j
                  d   j                  |k(              j                         }|r|S |r| j                  t              j                  t        t        j                  |k(  t        j                  |k(              j                         }|rU|r||_	        |r|j
                  r||j
                  d<   |r|j
                  r||j
                  d<   | j                          |S t        ||||||d      }| j                  |       | j                          | j                  |       |S )u/   Найти или создать клиентаcrm_lead_idr7   )r7   rx   )r*   rs   rt   ru   meta)r5   r   r6   r   r*   ry   astextr:   rs   rt   commitaddrefresh)r)   r*   rs   rt   r7   ru   rv   customers           r(   get_or_create_customerr      sE    88H%,,""i/m,33{B

 %' 	 O 88H%,,""i/%'

 %' 	 !&(,f%x}}/:m,IIKO &
	H FF8IIKJJxOr'   z/bitrix24/lead-createdrequestc                   K   | j                          d{   }t        |      }|j                  d      }|j                  d      }|j                  d      }|j                  d      xs |j                  d      }|j                  d      }|j                  d      xs d	}	|sd
ddS |j                         j	                  dd      j	                  dd      j	                  dd      j	                  dd      }
|
j                  d      sd|
 }
|rg	 |j                  d      \  }}}|	j                  d      \  }}t        t        |      t        |      t        |      t        |      t        |            }nd}|j                  t              j                  t        t        j                  dk(  t        j                  dk(  t        j                  dk(              j!                         }|sd
ddS |j"                  }t%        |||
|||      }|j                  t&              j)                  t*              j                  t        t&        j"                  |k(  t&        j                  dk(  t*        j,                  dk(              j/                         }d}|D ]0  }|j                  t*              j                  t*        j0                  |j2                  k(        j!                         }|sT|r|t5        |j6                        z
  }nt        j8                         }t;        |||      }t=        ||||      }|xs d|r|j?                  d      nd|r|j?                  d      nd||d }tA        ||j0                  |jB                  |j0                  |||jD                  xs |jD                  d|!	      }|jG                  |       |d"z  }3 |jI                          d#d$| |j0                  |d%S 7 #  d}Y }xY ww)&u  
    Обработка создания лида в Bitrix24
    
    Ожидаемые поля:
    - PHONE: телефон
    - EMAIL: email  
    - NAME: имя
    - UF_CRM_APPOINTMENT_DATE: дата приёма
    - UF_CRM_APPOINTMENT_TIME: время приёма
    Ndata[FIELDS][ID]zdata[FIELDS][PHONE][0][VALUE]zdata[FIELDS][EMAIL][0][VALUE]zdata[FIELDS][NAME]zdata[FIELDS][TITLE]%data[FIELDS][UF_CRM_APPOINTMENT_DATE]z%data[FIELDS][UF_CRM_APPOINTMENT_TIME]z14:00erroru    Телефон не указанstatusmessage rn   ()-+.:r/   	connectedTB   Активная интеграция Bitrix24 не найдена)r)   r*   rs   rt   r7   rv   zappointment.createdr   hours   Клиент%d %B%H:%Mcustomer_nameappointment_dateappointment_timer.   rI   	r*   customer_idtemplate_iduser_template_idscheduled_atpayloadchannelstrigger_typerv      successu   Обработан лид )r   r   r   scheduled_notifications)%formdictr=   striprp   
startswithsplitr   intr5   r   r6   r   r;   r   	is_activer:   r*   r   r   joinr   r   allrc   industry_template_idr   delay_hoursrq   rF   rL   strftimer   r   r   r|   r{   )r   r)   	form_datar   lead_id	phone_rawrt   r7   appointment_date_strappointment_time_strrs   daymonthyearhourminuteappointment_datetimer+   r*   r~   user_templatesscheduled_countuser_templateindustry_template	send_timer.   rI   r   	scheduleds                                r(   handle_bitrix_lead_createdr      s    " lln$I	?D hh)*G89IHH45E88()LTXX6K-LD  88$KL88$KLWPW!.PQQ OO%%c2.66sB?GGRPXXY\^`aEC E7 		(399#>C/55c:LD&#+D	3u:s3xD	3v;$   $ ((;'..
*+-!!T)	
 eg  !.rss%%I &H XX2388f **i7 **d2))-BB	
 
ce  O' (HH%56===#E#EE

%' 	 !  ,y?P?\?\/]]I )I ,B	;G%b)['J "3^J^ 4 = =g FdfJ^ 4 = =g Fdf,&
 * %11*--""++I/@/I/I.

	 	y1Q(T IIK /y9{{#2	 k %>	(#' s*   O;O.C;O;A%O1 8I7O;1O85O;z/bitrix24/appointment-soonc                   K   | j                          d{   }t        |      }|j                  d      }|j                  d      }|j                  d      }|j                  t              j                  t        t        j                  dk(  t        j                  dk(  t        j                  dk(              j                         }|sdd	d
S |j                  }d}	|rh	 d|v r&t        j                  |j                  dd            }	n=|j                  d      \  }
}}t        t!        |      t!        |      t!        |
            }	|	sddd
S d}|rt|j                  t"              j                  t        t"        j                  |k(  t"        j$                  d   j&                  t)        |      k(              j                         }|sddd
S |j                  t*              j-                  t.              j                  t        t*        j                  |k(  t*        j                  dk(  t.        j0                  dk(              j3                         }d}|D ]\  }|j                  t.              j                  t.        j4                  |j6                  k(        j                         }|sT|j8                  xs d}|	t;        |      z
  }|t        j<                         k  rt?        |||      }tA        ||||      }|j$                  r|j$                  j                  dd      nd|	jC                  d      |	jC                  d      ||d}tE        ||j4                  |jF                  |j4                  |||jH                  xs |jH                  dt)        |      	      }|jK                  |       |dz  }_ |jM                          dd| d|d S 7 #  d}	Y xY ww)!u   
    Триггер для напоминаний о приёме
    Запускается за N часов до приёма
    Nr   zdata[FIELDS][CONTACT_ID]r   r/   r   Tr   r   r   Trm   rn   r   u>   Не удалось распарсить дату приёмаrx      Клиент не найденzappointment.soonr      r   r7   r   r   r   r   r   r   r   u   Создано u'    напоминаний о приёме)r   r   r   )'r   r   r=   r5   r   r6   r   r;   r   r   r:   r*   r   ro   rp   r   r   r   ry   rz   r$   r   r   r   r   r   rc   r   r   r   rq   rF   rL   r   r   r   r   r|   r{   )r   r)   r   r   rG   r   r   r+   r*   r   r   r   r   r~   r   r   r   r   reminder_hoursr   r.   rI   r   r   s                           r(   handle_appointment_reminderr   r  s     lln$I	?DXX01N((56Kxx GH ((;'..
*+-!!T)	
 eg  !.rss%%I  		(&&'/'='=>N>V>VW_ac>d'e$ $4#9#9##> UD'/D	3u:s3x'P$  !.noo H88H%,,""i/m,33s;7GG

 %' 	 !.NOO XX2388f **i7 **d2))-??	
 
ce  O' +HH%56===#E#EE

%' 	 ! +66<"(9>+JJ	 x(( ,B	;G%b)[.Q KS--X]]..v~F]k 4 = =g F 4 = =g F,&
 * %11*--""++I/@/I/I+N+

	 	y1W+Z IIK $_$55\]#2 a %B	(#' s*   OOC	O!A'O JOOOz/bitrix24/appointment-completedc                 t  K   | j                          d{   }t        |      }|j                  d      }|j                  d      }|j                  t              j                  t        j                  d   j                  |k(        j                         }|sdddS |j                  t              j                  t              j                  t        t        j                  |j                  k(  t        j                  dk(  t        j                  d	k(              j!                         }|D ]  }|j                  t              j                  t        j"                  |j$                  k(        j                         }	t'        j(                         t+        |	j,                  
      z   }
|j                  j                  dd      dd}t/        |j                  |j"                  |j0                  |j"                  |
||j2                  d	|	      }|j5                  |        |j7                          ddiS 7 w)us   
    Триггер когда приём завершён
    Отправляет благодарность
    Nr   zdata[FIELDS][LEAD_ID]rx   r   r   r   Tzappointment.completedr   r7   r   zhttps://feedback.example.com)r   feedback_linkr   r   r   )r   r   r=   r5   r   r6   ry   rz   r:   r   r   r   r   r*   r   r   r   rc   r   r   rq   r   r   r   r   r   r|   r{   )r   r)   r   r   rG   r   r~   r   r   r   r   r   r   s                r(   handle_appointment_completedr     s     lln$I	?DXX01Nhh./G xx!((m$++w6eg  !.NOO XX2388f **h.@.@@ **d2))-DD	
 
ce  ( HH%56===#E#EE

%' 	 OO%	8I8U8U(VV	 &]]..v~F;

 *(( %11*--""++0&

	 	y/2 IIKi  i %s   H8H5HH8z/healthc                      dddS )uD   Проверка работоспособности webhook endpointokr   )r   servicer&   r&   r'   r(   health_checkr   4  s     ~66r'   )N)NN)NNNNN)3r#   fastapir   r   r   r   sqlalchemy.ormr   
sqlalchemyr   typingr	   r
   r   r   pydanticr   app.db.sessionr   app.db.modelsr   r   r   r   r   r   r   r   app.utils.encryptionr   re   loggingrouter	getLoggerr    r@   r   r   r$   rF   rL   r>   rJ   rr   r   postr   r   r   r=   r   r&   r'   r(   <module>r      sh   ? > "   (  !   /  	/0@	A			8	$') '%*7 %*s %*tAS %*_b %*P   C  kD>P  ilosis    @C  F# S S4Z .c  s sUYz <! ! ! !"888 :8 :	8
 *8 d
8 t8 8v %& &/JJJ 'JZ )* &/}}} +}@ ./ &/=!=!=! 0=!@ I7 7r'   