U
    f                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dlmZ d dl	Z	d dl
mZ d dlZd dlmZ d dlmZ d dlT d dlZd dlmZ d d	lmZ G d
d dejZdS )    N)md5)	randrange)Random)post)commit_all_ds)*)BeautifulSoup)
cmf_personc                       s  e Zd Zej dZejjdddddddd	d
dddddddg Ze	dddd fdd
Z
dd Ze	dd Ze	dddZe	dddZed d! Zd"d# Zd$d% Zdd&d'Zdd(d)Zdd*d+Ze	d,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Ze	dd6d7Zeeddd8ddd9d:d;Zeeddd<d=dd>d?Zddddddd@dAdBZ  fdCdDZ!dEdF Z"dGdH Z#dIdJ Z$e	dddK fdLdM
Z%dNdO Z&dPdQ Z'dRdS Z(dTdU Z) fdVdWZ*dXdY Z+dZd[ Z,d\d] Z-dd_d`Z.dadb Z/ddc fddde
Z0dfdg Z1dhdi Z2 fdjdkZ3ddmdnZ4 fdodpZ5 fdqdrZ6 fdsdtZ7 fdudvZ8e	ddwdxZ9dydz Z:eedd{dd|e%d}d~dZ;e	ddddZ<e	dddddZ=dd Z>edd Z?e	dć fdd	Z@e	dddZAdd ZBe	dddZCdd ZDdd ZEdddZFdd ZGeeddddddd ZHe	dd ZIdddZJe	dd ZKdd ZLe	dd ZMeeNdddd ZOdd ZPdd ZQdd ZRdd ZSdd ZTeedddd=dd ZU  ZVS )	CmfPersonz/custom/static/avatar/get_current_projectsget_current_userget_home_folderget_org_units_listmark_viewedpfeed_post_listregister_personsremove_avatarsearchZsend_message
set_avatar
start_chatZpublic_none_classmethodpublic_listpublic_get_org_units_list
public_get Nqueryfieldsfilterc             	      s>   | dpdddddddd	d
g	|d< t j||||d|S )NZfields_filternametextcodephoneemailphone_internalphone_mobilephone_2phone_assistantr   )getsuperr   )clsr   r   r   argskwargs	__class__ %./modules/person/models/cmf_person.pyr   -   s    $   zCmfPerson.searchc                 O   s   t dt| jS Nr   )strjoinreversedr   selfr*   r+   r.   r.   r/   reverse_name4   s    zCmfPerson.reverse_namec                 C   s   | j ddS )N.CmfPerson:00000000-0000-0000-0000-000000000001idr'   )r)   r.   r.   r/   system_person7   s    zCmfPerson.system_personTc                 O   s    t jjtjjddddddgdS )Nr   online_statuson_vacationrg_member_ofis_admin
two_factor)r9   r   )modelsr
   r'   gcurrent_personr9   )r)   Zcreate_args_kwargsr.   r.   r/   r   ;   s     zCmfPerson.get_current_userc                 C   sD   g }t jjdddtjjggddtjjgg|dD ]}|| q0|S )NOR	executorsINcmf_owner_id==r   r   )rA   
CmfProjectlistrB   rC   r9   append)r)   r   resultprojectr.   r.   r/   r   A   s    
zCmfPerson.get_current_projectsc                 O   s<   | j p| jpd}| jpd}| jp"d}| d| d|  S Nr    )	last_namelogin
first_namesecond_namestrip)r5   r*   r+   rS   rU   rV   r.   r.   r/   	full_nameI   s    

zCmfPerson.full_namec              	   O   sr   |  dg | jsltjd | dddd}|jdd || _t  |   W 5 Q R X tj|ddd	jdd | jS )
Nhome_folderi'  u   Мои документыhome)tree_parent	cmf_ownerordernor   Zsys_typeF)notifyu   Документ1)r[   r]   r   )load_fieldsrY   rA   Z	CmfFoldersavecmfutildisable_aclZCmfDocument)r5   r*   r+   Zfolderr.   r.   r/   r   P   s     
zCmfPerson.get_home_folderc                 C   s   | j p| jp| jS N)rX   rT   r"   r5   r.   r.   r/   gen_name_   s    zCmfPerson.gen_namec                 C   s   d}|rt |d}nF|r:tjj|ddgd}|r\|j}n"|r\tjj|ddgd}|r\|j}|std| d| d	| d
 dS | tjkrtj	}ntj
j| dd}||krdS dS )u   
        ! Публичное API для bzPython
        Метод проверки, что пользователь находится в группе
        NCmfPersonGroup--r9   r    r   r   r   uX   Ошибка вызова in_person_group: не найдена группа (group_code=z, group_name=z, group=)FT)Zid_only)ra   get_obj_id_by_anyrA   rf   sgetr9   	cmf_alertrB   current_usercurrent_person__member_ofCmfAccessListZsubject_full_group_list)r5   group
group_codeZ
group_nameZgroup_idZ	member_ofr.   r.   r/   in_person_groupb   s(    
zCmfPerson.in_person_groupc                 C   s   | j |||dS )u   
        ! DEPRICATED
        ! Публичное API для bzPython
        Для обратной совместимости
        )rP   	role_coderole)in_project_role)r5   rP   rt   ru   r.   r.   r/   has_project_role   s    zCmfPerson.has_project_rolec                 C   s   d}|rt |d}nF|r:tjj|ddgd}|r\|j}n"|r\tjj|ddgd}|r\|j}|std| d| d	| d
 dS t |d}| jjtj	||kS )u   
        ! Публичное API для bzPython
        Метод проверки, что пользователь назначен на Проектную роль
        role и project могут быть: объект, tuuid, code, name
        NCmfProjectRolerg   r9   rh   ri   ug   Ошибка вызова in_project_role - не найдена Проектная роль (role_code=z, role_name=z, role=rj   FrL   )
ra   rk   rA   rx   rl   r9   rm   valuer
   get_project_role_members)r5   rP   ru   rt   Z	role_namerole_id
project_idr.   r.   r/   rv      s     zCmfPerson.in_project_rolec                 C   s   t j|t  t j| }||d  || }|d k	r>t|S t }tjjdd|gdd|ggddgdD ]"}|j	 D ]}|
|jj qvqh|t j| |< t|S )Nparent=Zproject_rolemembersZproject_role_idrK   )APPZcache_in_project_role
setdefaultdictrM   setrA   ZCmfProjectRoleAssignr   
all_nestedaddr9   ry   )r)   r|   r{   Zproject_cacheZrole_cache_setZrulememberr.   r.   r/   rz      s    

z"CmfPerson.get_project_role_membersc                 C   s`   |  dddg d}| jrL| jrL| jtj  krL| jtj  krLd}| j|kr\|| _d S )Nr=   vacation_startvacation_endFT)r_   r   r   datetimeZutcnowdater=   )r5   Zcur_on_vacationr.   r.   r/   _calc_vacation   s    
zCmfPerson._calc_vacationc                 C   s   | j jr| j js| j dkrd S | j j}|| jd}|| jd }|d}t	|dkrl| j
sl|d | _
t	|dkr| js|d | _t	|dkr| js|d | _d S )Nr   rR   r         )r   
is_changedis_nullry   replaceVACATION_SUFFIXDOES_NOT_WORK_SUFFIXrW   splitlenrS   rU   rV   )r5   ZtmpZname_arrr.   r.   r/   _calc_from_name   s    


zCmfPerson._calc_from_namec                 C   sx   | j js<| jjs<| jjs<| jjs<| jjs<| jjs<| jjs<d S d}| jrRd| j }| jrdd| j	 }| j
 | | _ d S rQ   )r   r   rU   rV   rS   rT   r=   does_not_workr   r   rX   )r5   Zadd_strr.   r.   r/   
_calc_name   s,    	zCmfPerson._calc_namec                 C   sn   t tjjjtjjjtjjjtjjjd}| jrT|D ] }| jj	|r2| j| ||< q2|d sj| j
rjd|d< |S )N)
allow_baseZ
allow_ldapZallow_oauthZ	allow_ssor   T)r   rB   global_settingsZauth_options_allow_basery   Zauth_options_allow_ldapZauth_options_allow_oauthZauth_options_allow_ssoauth_optionsr'   r?   )r5   reskeyr.   r.   r/   get_auth_options1  s    
zCmfPerson.get_auth_optionsc                 C   sj  dddddgdddggddd	gdd
ddgd
dd	ggg}|rN|sN| dd|g g }tjj|ddddddddgddD ]}g }t|jj|jj|jj|j	j||j
j| |jjd}|jrd	|_|jdd |j
s|jstjjrdd |jD |d< ndd |jD |d< n(|jrt|jj|d< d	|_|jdd nqt| | qt|sJd	S t |ddd}td| d	S ) u   
        Отправляем учетки в аккаунт
        https://bcrm.carbonsoft.ru/project/Document/DOC-003025#spec-0-ldap
        ZANDrF   
user_localrJ   Tservicedesk_allowrT   !=NZ
is_supportZcmf_modified_at>zrg_member_of.ext_idcmf_deletedr   deleted_loginr"   r   	ext_loginzrg_member_of.system)r   r   include_deleted)rT   r   r"   r   r>   r   r   	old_loginZ	only_datac                 S   s   g | ]}|j r|jjqS r.   )systemr    ry   .0objr.   r.   r/   
<listcomp>`  s      z/CmfPerson.account_sync_push.<locals>.<listcomp>r>   c                 S   s   g | ]}|j jqS r.   )r    ry   r   r.   r.   r/   r   b  s     )Zeva_app_tokenusersZrpc_account_sync_push)r+   methodzauth/sync_accounts)rN   rA   r
   rM   r   rT   ry   r   r"   r   r   r   r   r`   r   rB   r   Zonly_system_grp_syncr>   r   Zgen_eva_app_tokenZcall_eva_account)r)   account_sync_lastforce_filterr   personr>   datar.   r.   r/   account_sync_push@  sV    

zCmfPerson.account_sync_push)	only_once
system_job)r   two_factor_optc           	      O   s  g }d}| s dddgddd gg} t jj| dddgdD ]}zF|jsVt j|j|jd	|_||j_|j  |  t	  |d
7 }W q6 t
k
r } z"t  |t| t| W 5 d }~X Y q6X q6d| }|r| dd| }t| tjd|d d S )Nr   r   rJ   Tr@   r$   r"   rK   r!   r"   r   u   Обработано u-   </br> Не удалось настроить:z</br>u)   Закончили настройку 2FA)r   )rA   r
   rM   r@   CmfAuthTwoFactorr$   r"   r   r`   commit_with_event	ExceptionZrollback_purge_eventrN   r1   rB   debugr2   ra   Zadmin_alert)	r   r   r*   r+   Zfail_personZcntr   er   r.   r.   r/   init_2fa_settingss  s0    


zCmfPerson.init_2fa_settingsz@hourly)r   r   Zschedulec              
   C   s   t d t jjdkr<t jjjdkr.td nt d dS dt j_t jjj}t jj  t j	  t
  z&tjj|| d dt j_t j	  W nV tk
r } z8t| t| t| |t j_d	t j_t j	  W 5 d}~X Y nX dS )
uz   
        Синхронизируем уровень доступа с accounts сервером
        :return:
        u6   Запуск синхронизации с eva_accountZin_progressi  u   Синхронизация пользователей зависла, запускаем форсированно повторноu2   Синхронизация уже запущенаN)r   closederror)rB   r   Z
global_varZaccount_sync_statusr   Zagerm   ry   Zset_nowr`   r   rA   r
   r   r   logging	exceptionr   )r   r   r   r.   r.   r/   account_sync_users  s,    





zCmfPerson.account_sync_users)slicer   order_bydo_count	do_unreadsearch_filterc             	   O   sN  t jjdddgddgd}	t }
|	D ]R}|jrRt|jjt jrR|jjrR|
| q$| j	jdd |
 D kr$|
| q$|rt jjd	d
dd| j	jggddddgddtjj	ggddttdd |
ggdS ddddgddtjj	ggddttdd |
gg}|r"dddgd	d
dd| j	jgg|g}|r2|| t jj||ddg|d}|S )NZ	list_typerJ   Zpfeedr}   zparent.is_defaultrK   c                 S   s   g | ]}|j jqS r.   )r9   ry   )r   r   r.   r.   r/   r     s     z-CmfPerson.pfeed_post_list.<locals>.<listcomp>Zperson_viewsz
NOT EXISTS	person_idr~   rF   cache_status_typer   ZOPENrI   listsrH   c                 S   s   | j S rc   r8   xr.   r.   r/   <lambda>      z+CmfPerson.pfeed_post_list.<locals>.<lambda>r   c                 S   s   | j S rc   r8   r   r.   r.   r/   r     r   z-status_in_progress_start-cmf_created_at)r   r   r   r   )rA   ZCmfListrM   r}   
isinstancery   rL   
is_defaultrN   r9   Zall_relation_personsCmfTaskcountrB   rC   map)r5   r   r   r   r   r   r   r*   r+   r   Zmy_listsZlstZfltZ	post_listr.   r.   r/   r     sB    


 
zCmfPerson.pfeed_post_listc                    s   t  j|fd| ji|S )Nr   )r(   r   r9   )r5   Zobj_idrD   r+   r,   r.   r/   r     s    zCmfPerson.mark_viewedc                 O   s   d S rc   r.   r4   r.   r.   r/   public_mark_viewed  s    zCmfPerson.public_mark_viewedc                 C   s   g }| j jrtj }|jdd | j D krtjjdd| jggdgd}|rZdd |D }|sdd|jggd	d
d| jggg}tjj|d	gdD ]h}t }|g|_	d|_
|  |j	|  |jdd |jD ]}|j	|  |jdd q|| q|S )Nc                 S   s   g | ]
}|j qS r.   r8   r   r.   r.   r/   r     s     z.CmfPerson.create_p2p_chats.<locals>.<listcomp>rG   rH   p2prK   c                 S   s   g | ]}|j r|qS r.   )r   r   r.   r.   r/   r     s      r>   r9   zNOT INr7   Tr   )r>   r   rA   rf   
user_groupr9   ZCmfChatGrouprM   r
   rG   r   r`   rN   Ztopics)r5   r   Zusr_grpZ	cur_chatsr   r   rq   Ztopicr.   r.   r/   create_p2p_chats  s2    

zCmfPerson.create_p2p_chatsc                 C   s2   | j s
d S tjj| jkr$tddd tj  d S )Nu1   Нельзя удалить самого себяTabort)r   rB   rC   r9   rm   rA   rp   check_admin_moderd   r.   r.   r/   
_check_del  s
    zCmfPerson._check_del)include_systemis_userc                   s.   |s| dd |dkr d|d< t j||S )Nr   FTr   )r   r(   rM   )r)   r   r   r*   r+   r,   r.   r/   rM     s
    zCmfPerson.listc                 C   s^   | j rtjj| drd S | jr"d S tjj| dd}|rJ|  td d S tj| d  d S )Nr   Tr   r   u   Warning. CmfPerson был удален и некорректно востановлен. Обратитесь в Техническую поддержку)	r   rA   CmfPersonVarrl   r   r'   restorerm   r`   )r5   Z
deleted_pvr.   r.   r/   _check_person_var  s    zCmfPerson._check_person_varc                 C   sp   | j s| jrd S | jjrF| jjrF| jjsF| jjj dkrFtddd | jj	rlt
jd| jd}|  || _d S )Nr   u?   Контакт не может быть без компанииTr   )typer   )r   r   companyr   oldnewr   loadrm   r   rA   Z
CmfCompanyrX   r`   )r5   Znew_companyr.   r.   r/   _calc_company  s    "zCmfPerson._calc_companyc                 C   sL   | j r| jsdS tjdg | jD ]"}tjjD ]}|j|_|  q0q$dS )u   
        Вычисляем список избранного по умолчанию для новых пользователей
        Nzperson_var.favorites)is_newr   rB   rC   r_   
person_varZ	favoritesr`   )r5   r   Zcurrent_person_varr.   r.   r/   _calc_default_favorites   s    
z!CmfPerson._calc_default_favoritesc                 C   s   | j r| jsd S d S rc   )r   r   rd   r.   r.   r/   _calc_avatar-  s    zCmfPerson._calc_avatarc                    s8   t   ddddddddd	d
dddddddddddg S )NrT   notify_email
notify_smsr!   r$   rolesprimary_rolezcompany.typer   r   r   r=   r   r   rS   rU   rV   r"   r   ztwo_factor.two_factor_opt)r(   save_preload_fieldsrd   r,   r.   r/   r   3  s.                     zCmfPerson.save_preload_fieldsc                 C   s   | j r| j jsdS g }tjjdd| gdddggdD ] }|d|j d	|j d
 q4|rd|}d| j d	| j d| }tj| 	 d|d
  dS )zY
        https://bcrm.carbonsoft.ru/project/Document/DOC-003685#spec-eva-account
        NresponsiblerJ   r   r   ZCLOSEDr   z	<a href="z">z</a>z<br>z</a> uM   Обработайте задачи уволенного сотрудника)r   r   r   )r   r   rA   r   rM   rN   Zhrefr   r2   get_supervisorr`   )r5   ZlinksZtaskr   r.   r.   r/   _check_does_not_work:  s    

zCmfPerson._check_does_not_workc                    s    fdd |  ddg d}| jrV| jjrB| jjjrB| jjj}n| jjrV | jj}|stj }|j	  |jr|j
 d }|S )u   
        Идем по структуре отделов роли и получаем первого руководителя
        c                    s6   | j rtjj| j dS | dg | jr2 | jS d S )N)r   ztree_parent.head)headrA   r
   r'   r_   r[   )Zorg_unit	recursionr.   r/   r   P  s    
z+CmfPerson.get_supervisor.<locals>.recursionzprimary_role.supervisor.personzprimary_role.tree_parent.headNr   )r_   r   
supervisorr   r[   rA   rf   Zadmin_group
rg_membersr   r   )r5   r   Z	admin_grpr.   r   r/   r   L  s    	

zCmfPerson.get_supervisorc              	   C   s   | j jsd S i }| dg | j D ]^}|js.q"t|jdD ]@}| }||krvtd||  d| d| dd q>|||< q>q"d S )Nz*rg_member_of.incompatible_combination_code,u\   Пользователь не может участвовать одновременно в u    и uS   , так как у них указан Код запрета совмещения: Tr   )r>   r   r_   Zincompatible_combination_coder1   r   rW   rm   )r5   ZcodesZgrZgr_coder.   r.   r/   %_check_roles_incompatible_combinationj  s    
z/CmfPerson._check_roles_incompatible_combinationFc                 C   sP   | j js|sd S | j sd | _n.| jjr4| j d | _n| j| j krL| j d | _d S )Nr   )r   r   r   r   )r5   r   r.   r.   r/   _calc_primary_role  s    zCmfPerson._calc_primary_rolec                 C   sB   | j rtjj| dsdS tjj| dD ]}d|_|jdd q&dS )uN   Надо пометить что данные не засинканы
        r   NTr   )r   rA   CmfAuthPluginDatar   rM   Zdirtyr`   )r5   	auth_datar.   r.   r/   _check_auth_data  s
    zCmfPerson._check_auth_data)save_kwargsc                   s0   | drtddd t j|d|i| d S )Nr   u   Назначение или открепление должности пользователю необходимо производить в "Структуре" в карточке должностиTr   r  )r'   rm   r(   update)r5   r  r*   r+   r,   r.   r/   r    s    
zCmfPerson.updatec                 C   s8   | j r4tjjr4| js4| tjfkr4tj| j| j	d| _d S )Nr   )
r   rB   r   r   r@   r;   rA   r   r$   r"   rd   r.   r.   r/   
_check_2fa  s     zCmfPerson._check_2fac                 C   sp   | j jsd S d }| j jD ]}|j r|jj} q4q|s<d S | jsVtj| j	| j
d| _|| j_| jjdd d S )Nr   Tr   )r>   r   r   r   r   ry   r@   rA   r   r$   r"   r`   )r5   r   grpr.   r.   r/   _check_2fa_group  s    
zCmfPerson._check_2fa_groupc                    s<   | j r| j| j kr| j | _|   |   t j|| d S rc   )rT   r    r   _calc_servicedesk_allowr(   _save_importr4   r,   r.   r/   r	    s
    zCmfPerson._save_importr   c                 K   sv   |dkrd S | j jsd S tjs@tjs@tjtjks@tjj	dddrDd S tj
jdddgd}|jjtjkrrtd	d
d d S )Nr   r   FZraise_errorr    rJ   ZProjectAdminsr   u  Изменение членства в группах на карточке пользователя для Проектных администраторов временно недоступно. Откройте группу и добавьте пользователя там.Tr   )r>   r   rB   Zdisable_permissionsZacl_admin_moderC   r;   rA   rp   r   rf   r'   r9   ry   ro   rm   )r5   depthr+   Zproject_admins_groupr.   r.   r/   _tmp_changing_member_of_alert  s    z'CmfPerson._tmp_changing_member_of_alertc                    s  ddddddddd	d
dddddddddddddddddg}|  | j | jr`tj| jj d S | jrztj| jj d S | j	jpd}| j
r|d| j
j 7 }| jr| j| j
kr|d| jj 7 }||d< | stj| jj d S d}|D ]}|dkr | jD ]}|j	jr|d|j	j 7 }qq|dkrT| jrr| jj	jrr|d| jj	j 7 }q| | jr|d| | j 7 }q||d< t jf |S ) Nr   r"   r!   r#   r$   r%   r&   Z
ip_addressZemail_2ZzoomZsnapchatZlinkedinZfacebookZvkokZ	instagramZskypeZslackZwhatsappZ	messengerZviberZtelegramZwork_positionemployee_numberz
roles.namezprimary_role.namer   r   rR   r   r   )r_   Zfull_search_fieldsr   rA   ZCmfFullSearchZ
mark_cleanr9   ry   Z
cmf_hiddenr   rT   r"   rW   r   r   r(   full_search_index)r5   r+   Ztext_fieldsr   r   frr,   r.   r/   r    sf                     	



zCmfPerson.full_search_indexc                    s|  | j f | |   | jjr*| jr*|   | jrD| j| jkrD| j| _|   |   | 	  | 
  |   |   |   | jjr| jr| jjs| jjstddd |   |   |   |   |   | jjrtjjdd| ddd| j| jdd	d
 | jjD dd
 | jD did	 tjdkr| j js>| j!jrt"j#j$ddsZtddd tj%j&| jd}|sztd n>| j jr| j rd|_'nd |_'| j!jr| j!|_!|j(dd | j)r| j*stj+j&dd| _*| j,jrtj-j.ddrn*t"j#| / krntd| /  ddd t0t1| j(||}| 2  | j3sH| j4rTt5tj1j6 | 7  | j)rxtj8| d}|(  |S )Nu   Для включения SMS уведомлений необходимо указать номер мобильного телефонаTr   Zperm_updater
   r  r   r   c                 S   s   g | ]
}|j qS r.   r    r   rB   r.   r.   r/   r   (  s     z"CmfPerson.save.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r.   r  r  r.   r.   r/   r   )  s     )r   r   )	operatecmf_model_namer}   result_statuscurrent_transactionsecurity_levelparent_nameparent_codeZ
audit_dataFalseZIBAdminsrr   u   Изменять настройки паролей разрешено только Администраторам ИБ из группы IBAdmins)rT   uG   Пользователь не синхронизирован с accountr   r   )r   Fr
  uw   Поле может редактировать только Администратор или Руководитель(rj   )r}   )9r  r   r   r   r   rT   r    r   r   r   r   r   r   r   r   r$   numberr!   rm   r   r  r  r  r  r>   rA   CmfAuditaudit_eventr   r   configZEVA_ACCOUNT_USEZpassword_must_changeZpassword_changed_daterB   rn   rs   ZCmfAuthr'   Zpassword_expires_must_changer`   r   ZcalendarZCmfCalendarno_staff_control_todayrp   r   r   r(   r
   r   r   r   schedule_deferred_jobr   _check_notify_opt_cache_reloadZCmfTimeTracker)r5   r*   r+   Zauthr   Zperson_timetrackerr,   r.   r/   r`     s    




zCmfPerson.savec                    s   |  dddg tjjdd| gdgd}|rDtd| d	d
d d S | jrrdtj d }| d| j | _| 	  |drtj
j| d
dD ]}|j|| qtjj| dD ]}|j|| qt j|| ttj tj  d S )Nr\   r   r  r   rJ   Zauth_pluginrK   u;   Пользователь синхронизирован с u9   , сначала отключите интеграцию.Tr   ZDELz%Y%m%d%H%M%SrR   ZTEXKOM_db_deleter   r   )r_   rA   r   r'   rm   r  r   nowstrftimer   ZCmfPersonViewrM   deleter   r(   r"  r
   r   ZCmfProjectNotifySchemeZtrigger_reload)r5   r*   r+   r  prefixpvarr,   r.   r/   r&  X  s"    

zCmfPerson.deletec                    s8   | j rt| jd| j j| _ t j|| ttj	 d S r0   )
r  resubZdelete_prefix_patternry   r(   r   r"  r
   r   r4   r,   r.   r/   r   p  s    zCmfPerson.restorec                 C   sP   |rLt  }||d | }tj d| d}tj	|sLt
| |S )Nutf8/)hashlibr   r  encode	hexdigestr5   _AVATAR_DIRECTORYospathexistsmakedirs)r)   rT   mZavatar_hashavatar_directoryr.   r.   r/   
avatar_dirw  s    
zCmfPerson.avatar_dirc                 O   sf   t j| jj}tj|rNt|D ]&}| | }tj	|r&t
| q&ttj| jjgd d S )Nr*   )rA   r
   r8  rT   ry   r2  r3  isdirlistdirisfileremover"  set_gravatarr9   )r5   r*   r+   r7  filefilepathr.   r.   r/   r     s    zCmfPerson.remove_avataru<   Регистрация нового пользователя)r   descriptionshow_bg_progressbar)emailsc                 O   sz  ddl m} g }tjtjd s0td |S tj	tj
krtjjrbtj	jstjjstj	jdds| D ] }tjjddd	d
dd||d qftdtj	 | }tj }| D ]}|d	krqtjjddd	ddd||d t|tjttt ttt d d|d}td|  tj	jj|d< t|}	t|	}
tj j!dgddj"j}|d|
|d}|j#t$ddd d|t%j&dd}td| d|  |j'dks|j(d kr|) }td!| d"|  qd#d$|g}td%|  tj*j!|d&}|std' tj*|||gdd(}n&td)|j+ d* |j,-| d|_t./  |0  W 5 Q R X |-|j1j td+ q|S ),u   
        Регистрируем новых пользователей по email
        :param emails:
        :return:
        r   )sessionz/custom/org_namezCregister_persons: WARNING: org_name is not set, can't invite peopleZAllowInviter  Zuser_inviter
   NZfailTr   )r  r  r}   r  r  r  r  r  u.   Операция не доступна для r  r   i:	 Zguid)rT   ZissZiatZexpZjtir+  zregister_persons:frominvite_must_change_password)r   Zcache_inmemoryZinvite_by_email)r"   actioninvite_tokenrF  )ZabsoluteZinternalzauth/signup   )r   cookiestimeout,    zSigned up successfullyuE   ERROR: Не удалось отправить приглашение z: r    rJ   u"   Ищем пользователя r   u)   Создадим пользователя)rT   r"   r>   r   u(   Добавим пользователя u    в группуz!register_persons: person saved ok)2requestsrD  r2  r3  r4  r   PROJECT_DIRrB   r   rC   r;   rn   r   r?   r   Zallow_user_inviters   rA   r  r  ZCmfPermissionErrorrf   r   r   ZAPP_FQDNr1   inttimer"   ry   Z
create_jwtZrsa_sign_pack_jwtZCmfGlobalSettingsr'   rF  r   Zauth_base_hrefrequestrJ  status_coder   Zjsonr
   r   r>   rN   ra   rb   r`   r9   )rC  r*   r+   rD  rO   r"   srq   ZpayloadZjwtrH  rF  r   r   r   r   r.   r.   r/   r     s    


    


     


zCmfPerson.register_persons)r   c                O   s   dg}| j |d|i|}|S )Navatar_filenamer   r:   )r)   r   r*   r+   r   r.   r.   r/   r     s    zCmfPerson.public_get)r   r   c                O   s   d S rc   r.   )r)   r   r   r*   r+   r.   r.   r/   r     s    zCmfPerson.public_listc                 O   sb   | j s
dS tjjdd| jgdgd}|r2|d }n,tj| jd}| j|_| g|_| |_|	  |S )uq   
        Возвращаем объект, с которым нужно начать переписку
        NZprimary_contact_idr~   r   )r   r   r   )r   )
r!   rA   ZCmfDealrM   r9   r   r   ZcontactsZprimary_contactr`   )r5   r*   r+   ZdealsZdealr.   r.   r/   r     s    
zCmfPerson.start_chatc                 C   s   | j jr| j jd k	r| j jS tjjdd| jgddgd}|rT|j dkrt|jtj	jkrtdtjj j
d d| j _| j jS |j r|j j
|j j pd}|j j|d| j _| j jS )	Nr   rJ   r<   rK   Z	invisibleZoffline)Zjs_idr   r   )r<   Z
is_defined_valuerA   r   r'   r9   r   rB   rC   choicesry   )r5   r   r   r.   r.   r/   _online_status   s    
zCmfPerson._online_statusc                    s   |dkr|sg }|dd|gg}|dkrJ|rJ| drJ|s<g }|dddgg}|dkr||sZg }|d	d
ddgdddgdddggg}t j|f|||d|S )Nr   r   rJ   r   r   Zis_internalTruer>   rF   r   Fr    r~   ZAdminsZUsers)object_fields	object_idr   )r'   r(   field_options_list)r)   Zrelation_field_namerZ  r[  r   r+   r,   r.   r/   r\    s&    " zCmfPerson.field_options_listc           	   
   C   s   t d|  |s"dddddg}zt|d}t|tjjdd	  d
}ddd|gdd|gdd|gdd|gg}|r||g}tjj	||d}t d|  |W S  t
k
r } zt d|  W Y d	S d	}~X Y nX d	S )us   
        Ищем персону по номеру телефона
        :param phone:
        :return:
        u4   Ищем пользователя по номеру r!   r#   r$   r%   r   ZRUr   Nz;%rF   ZLIKErJ   rK   u.   Возвращаем пользователя %   Неправильный номер: )rB   r   phonenumbersparseZformat_numberZPhoneNumberFormatZE164rA   r
   r'   r   )	r)   r!   r   r   Z	phone_objZformat_phoner   r   r   r.   r.   r/   get_by_phone   s&    
zCmfPerson.get_by_phonec                    sX   g }i }|  dg | jD ]$}|jrg }|||jj< || q fdd  | |S )Nzroles.tree_parent_idc                    s\   i }t jjdd| gddgdD ],}| |j d| |jr| |j ||j< q|rX | d S )Nr9   rH   tree_parent_idr   rK   r   )rA   Z
CmfOrgUnitZslistr9   insertra  )Zou_idsZou_ids_nextZouquery_our.   r/   rd  E  s    z.CmfPerson.get_org_units_list.<locals>.query_ou)r_   r   ra  ry   rN   )r5   rD   rE   rO   Zou_ids_firstr  Zou_listr.   rc  r/   r   :  s    
	zCmfPerson.get_org_units_listc              
   C   s   | j |||d}|s~z*td|  tj||d}|  W n> tk
r| } z td| d|  W Y d S d }~X Y nX td|j  |S )Nr   u:   Создаем пользователя с номером )r!   r   r]  rL  u@   Возвращаем пользователя с номером )r`  rB   r   rA   r
   r`   r   r!   )r)   r!   r   r   r   r   r.   r.   r/   get_or_create_by_phoneR  s    z CmfPerson.get_or_create_by_phonec                 C   s2   t t|dd  j|d}|| jj| dS )u3   
        Позвонить клиенту
        :r   r8   N)varsrA   r   r'   callbackr!   Znumber_e164)r5   Z
channel_idrh  channelr.   r.   r/   
phone_call`  s    zCmfPerson.phone_callc                 O   s0   t j| jst | j t| j d| S )Nr-  )r2  r3  r4  r1  r5  pathlibPath)r5   
image_hashr*   r+   r.   r.   r/   avatar_pathg  s    zCmfPerson.avatar_pathc              	   O   s   |sX| j  r*| | j }| r*|  d | _ | jdd |rTttj| j	j
gd d S |}t|trpt|}t| jj
d }| d| _ | | j }	|	d}
|
| W 5 Q R X | jdd d S )NTr   r9  r,  z.jpegwb)rU  r   rn  r4  unlinkr`   r"  r
   r>  r9   ry   r   r1   base64Zurlsafe_b64decoder.  r   rT   r/  r0  openwrite)r5   image
image_typer>  r*   r+   rn  Z
image_datarm  Z
image_pathZ
image_filer.   r.   r/   r   l  s&    


zCmfPerson.set_avatarc              
   C   s   | j std dS t }|| j j  	d d}d|
  d| d}zt j|tjdd	}W n: tk
r } ztd
|| W Y dS d}~X Y nX |jdkrtd
||j dS |jS )u>   
        Получаем аватарку с gavatar
        u/   Fetch gravatar skip: не задан логинNr,  Zqwez https://www.gravatar.com/avatar/z/avatar.jpg?d=z&s=200r   )rK  u.   Ошибка запроса к gravatar {}: {}rM  )rT   rB   r   r.  r   r  ry   lowerrW   r/  r0  ra   Zrequests_sessionr'   rR  r*   r   r   r   formatrS  r   Zcontent)r5   r6  defaultZurlr   r   r.   r.   r/   fetch_gravatar  s     

zCmfPerson.fetch_gravatar<   u   Установка gravatar)r   Zsoft_time_limitrA  rB  c                 K   s<   t jj| d}|t j| | }|j|ddd d S )Nr8   ZjpegF)ru  r>  )rA   r
   r'   r_   r   ry  r   )r   rE   r   rt  r.   r.   r/   r>    s    zCmfPerson.set_gravatarc                 O   s   d S rc   r.   )r)   r*   r+   r.   r.   r/   r     s    z#CmfPerson.public_get_org_units_listc                 C   s*  |  dg | jjs$|s$| jjs$d S | jjr~tjjdd}|t| jjt| jj	 kr\d| _|t| jj	t| jj kr~d| _d}t
jjr| jsd}| jjr| js|rtddd n|r| j|kr|| _| jjr&tjjdd}|  dg | jr|| jkr&| j| n|| jkr&| j| d S )	Nr   ZServiceDeskClientr  TFu   Нельзя снять опцию у пользователя, т.к. она активирована через Проектную роль или включена глобальная опция "Разрешить доступ всем"r   r>   )r_   r   r   r>   rA   rf   r'   r   r   r   rB   r   Zservicedesk_allow_auth_guestsr   rm   rN   r=  )r5   r   Zsdesk_groupr   r.   r.   r/   r    s@    

z!CmfPerson._calc_servicedesk_allowc                 C   s   |t jkrt j| S tjj|ddddddddd	d
dddddddgd}|s^td| d dS |jsj|jrt	d| d dS |j
j|jj|jj|jj|jj|jj|jj|jj|jj|jj|jj|jj|jj|jjdt j|< t j| S )u_   
        Кешированное получение опций уведомления
        Temail_if_spectatoremail_if_authoremail_if_owneremail_if_responsibleemail_if_mentionsemail_if_self_changesr   r   	notify_osr!   r$   r   r"   rT   r   r   )r9   r   r   u8   Пользователь не существует (ID: rj   NuV   Пользователь удален или не работает(уволен) (ID: )r{  r|  r}  r~  r  r  r   r   r  r!   r$   r   r"   rT   )r   cache_person_notify_optrA   r
   r'   rm   r   r   rB   r   r{  ry   r|  r}  r~  r  r  r   r   r  r!   r  r$   r   r"   rT   )r)   r   r   r.   r.   r/   get_notify_opt_cached  sT    


zCmfPerson.get_notify_opt_cachedc                 C   s   | j s| jjs| jjs| jjs| jjs| jjs| jjs| jjs| j	js| j
js| jjs| jjs| jjs| jjs| jjs| jjs| jjsd S td d| jji}td| d S )Nz!person_notify_opt::reload triggerr   CmfPerson:changed)r   r   r   r   r{  r|  r}  r~  r  r  r   r   r  r!   r$   r   r"   rT   printr9   ry   cmf_emit_server_eventr5   r   r.   r.   r/   r#    sL    	
z(CmfPerson._check_notify_opt_cache_reloadc                 C   s   t d ddi}td| d S )Nz"flush_all_notify_opt_cache triggerr   ALLr  )r  r  r  r.   r.   r/   flush_all_notify_opt_cache.  s    z$CmfPerson.flush_all_notify_opt_cacher  )ri  c                  K   sF   t d | d}|d}|dkr,i t_ntj|d  t d d S )Nz&person_notify_opt_change::reload startr   r   r  z%person_notify_opt_change::reload done)r  r'   r   r  pop)rE   r   r   r.   r.   r/   on_person_notify_opt_change4  s    

z%CmfPerson.on_person_notify_opt_changec                 C   s4   t jj| dgd}|r"|jr"|jS tjjtjjdS )Nbrowser_timezone)r   r   )Ztz)rA   r   r'   r  r$  r   timezoneZutcr5   r   r.   r.   r/   get_current_datetime@  s    
zCmfPerson.get_current_datetimec                 C   s`   |  j d7  _ | j tjjkrPtjjr,d| _ntj tjtjjj	d | _
d| _ | jdd d S )Nr   T)Zminutesr   r   )auth_fail_try_counterrB   r   Zauth_fail_try_countauth_fail_permanent_blockr   r$  Z	timedeltaauth_fail_timeoutry   auth_fail_block_end_dater`   rd   r.   r.   r/   auth_fail_hookI  s    
zCmfPerson.auth_fail_hookc                 C   s   d| _ | jdd d S )Nr   Tr   )r  r`   rd   r.   r.   r/   auth_success_hookW  s    zCmfPerson.auth_success_hookc                 C   sf   t jjr| jrtddd nF| jr<tdt jj ddd n&| jrPtddd n| jrbtddd d S )Nul   Учетная запись заблокирована, обратитесь к администраторуTr   un   Превышено количество попыток ввода пароля, повторите через u    минутu   Учетная запись заблокирована за неактивность, обратитесь к администраторуuR   Пользователь больше не является сотрудником)rB   r   r  rm   r  r  Zauth_inactive_blockr   rd   r.   r.   r/   auth_check_ban[  s    zCmfPerson.auth_check_banc                 C   s&   |  ddg | jD ]}|  qd S )Nzperson_var.browser_timezonez,person_var.person.staff_control_blocked_date)r_   r   Zget_overdue_deadline_tasksr  r.   r.   r/   calc_staff_control_blockede  s    
z$CmfPerson.calc_staff_control_blockedz@dailyc                  C   s,   t jjdddgdD ]} d| _|   qd S )Nr!  r~   Tr   F)rA   r
   rM   r!  r`   r   r.   r.   r/   %cron_drop_no_staff_control_today_flagk  s    z/CmfPerson.cron_drop_no_staff_control_today_flag)T)N)NNN)NN)NNN)N)N)F)r   )N)NNN)NN)NN)NNT)F)W__name__
__module____qualname__r   rO  r1  r	   r
   Zapi_methodsclassmethodr   r6   r;   r   r   propertyrX   r   re   rs   rw   rv   rz   r   r   r   r   r   staticmethodZcmf_deferred_jobr   r   r   r   r   r   r   rM   r   r   r   r   r   r   r   r   r   r  r  r  r  r	  r  r  r`   r&  r   r8  r   r   r   r   r   rX  r\  r`  r   re  rj  rn  r   ry  r>  r   r  r  r#  r  Zon_server_eventr  r  r  r  r  r  r  __classcell__r.   r.   r,   r/   r
      s   


 


W2
!	
		
4[
	T



8
5

	
r
   )rq  Zbinasciir.  rk  shutilrQ  r   Zrandomr   r^  ZCryptor   rN  Zrequests.apir   Zcmf.data_providers.baser   Zcmf.includer   Zbs4r   Zmodules.person.fieldsr	   r
   r.   r.   r.   r/   <module>   s"   