U
    ̙h                    @   sf   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T d dlZd dl	m
Z
 G dd de
jZdS )    N)commit_all_ds)*)
cmf_personc                       s4  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dddddg Zdd 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/d0Zdd1d2Ze
d3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Ze
dd=d>Zeed"d"d?ddd@dAdBZeed"d"dCdDddEdFZ dddddddGdHdIZ! fdJdKZ"dLdM Z#dNdO Z$dPdQ Z%e
dddR fdSdT
Z&dUdV Z'dWdX Z(dYdZ Z)d[d\ Z*d]d^ Z+ fd_d`Z,dadb Z-dcdd Z.dedfdgdhZ/didj Z0dkdfdldmZ1dndo Z2dpdq Z3ddsdtZ4dudv Z5ddw fdxdy
Z6dzd{ Z7d|d} Z8 fd~dZ9dddZ: fddZ;dd Z<d߇ fdd	Z= fddZ> fddZ?e
dddZ@dd ZAeeddddd ZBeed"dd"ddrde&dddZCe
ddddZDe
dddddZEdd ZFedd ZGe
d fdd	ZHe
dddZIdd ZJe
dddZKdd ZLdd ZMdddZNdd ZOeed"ddd"ddd ZPe
dd ZQdddZRe
dd ZSdd ZTe
ddĄ ZUeeVddƍddȄ ZWddʄ ZXdd̄ ZYdd΄ ZZddЄ Z[eed"d"ddDddӄ Z\ddՄ Z]  Z^S )	CmfPersonz/custom/static/avatar/get_current_projectsget_current_userget_home_folderget_org_units_listget_auth_fail_block_end_dateset_auth_fail_block_end_dateget_auth_fail_permanent_blockset_auth_fail_permanent_block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unblockc                 O   st   |   std d S tjjddsFtd tjjdd| ddd	d
 d S | d  tjjdd| ddd	d
 td d S )Nu6   Пользователь не заблокированFZraise_erroru   У вас нет правZuser_unblockr   failT   )operatecmf_model_nameparentresult_statuscurrent_transactionsecurity_levelsuccessu3   Пользователь разблокирован)r
   	cmf_alertmodelsCmfAccessListcheck_admin_modeCmfAuditaudit_eventr   selfargskwargs r-   %./modules/person/models/cmf_person.pyr   )   s(    
   

   zCmfPerson.unblock 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_assistantr0   )getsuperr   )clsr1   r2   r3   r+   r,   	__class__r-   r.   r   :   s    $   zCmfPerson.searchc                 O   s   t dt| jS Nr/   )strjoinreversedr4   r)   r-   r-   r.   reverse_nameA   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_personD   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)rI   r2   )r$   r   r=   gcurrent_personrI   )r?   Zcreate_args_kwargsr-   r-   r.   r   H   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==r3   r2   )r$   
CmfProjectlistrQ   rR   rI   append)r?   r2   resultprojectr-   r-   r.   r   N   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)r*   r+   r,   rb   rd   re   r-   r-   r.   	full_nameV   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ordernor4   Zsys_typeF)notifyu   Документ1)rj   rl   r4   )load_fieldsrh   r$   Z	CmfFoldersavecmfutildisable_aclZCmfDocument)r*   r+   r,   Zfolderr-   r-   r.   r   ]   s     
zCmfPerson.get_home_folderc                 C   s   | j p| jp| jS N)rg   rc   r8   r*   r-   r-   r.   gen_namel   s    zCmfPerson.gen_namec                 C   s   d}|rt |d}nJ|r<tjj|ddgdd}|r`|j}n$|r`tjj|ddgd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--rI   T)r6   r2   cache_inmemory)r4   r2   rw   uX   Ошибка вызова in_person_group: не найдена группа (group_code=z, group_name=z, group=)F)Zid_only)rp   get_obj_id_by_anyr$   ru   sgetrI   r#   rQ   current_usercurrent_person__member_ofr%   Zsubject_full_group_list)r*   group
group_codeZ
group_nameZgroup_idZ	member_ofr-   r-   r.   in_person_groupo   s(    
zCmfPerson.in_person_groupc                 C   s   | j |||dS )u   
        ! DEPRICATED
        ! Публичное API для bzPython
        Для обратной совместимости
        )r_   	role_coderole)in_project_role)r*   r_   r   r   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CmfProjectRolerv   rI   )r6   r2   )r4   r2   ug   Ошибка вызова in_project_role - не найдена Проектная роль (role_code=z, role_name=z, role=rx   Fr[   )
rp   ry   r$   r   rz   rI   r#   valuer   get_project_role_members)r*   r_   r   r   Z	role_namerole_id
project_idr-   r-   r.   r      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 )Nr   =Zproject_rolemembersZproject_role_idrZ   )APPZcache_in_project_role
setdefaultdictr\   setr$   ZCmfProjectRoleAssignr   
all_nestedaddrI   r   )r?   r   r   Zproject_cacheZrole_cache_setZrulememberr-   r-   r.   r      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 )NrM   vacation_startvacation_endFT)rn   r   r   datetimeZutcnowdaterM   )r*   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/   ra   r      r   )r4   
is_changedis_nullr   replaceVACATION_SUFFIXDOES_NOT_WORK_SUFFIXrf   splitlenrb   rd   re   )r*   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 r`   )r4   r   rd   re   rb   rc   rM   does_not_workr   r   rg   )r*   Zadd_strr-   r-   r.   
_calc_name   s,    	zCmfPerson._calc_namec                 C   s~   |  dddg ttjjjtjjjtjjjtjjjd}| j	rd|D ] }| j	j
|rB| j	| ||< qB|d sz| jrzd|d< |S )Nauth_optionsrO   
is_support)
allow_baseZ
allow_ldapZallow_oauthZ	allow_ssor   T)rn   r   rQ   global_settingsZauth_options_allow_baser   Zauth_options_allow_ldapZauth_options_allow_oauthZauth_options_allow_ssor   r=   rO   )r*   reskeyr-   r-   r.   get_auth_options>  s    
zCmfPerson.get_auth_optionsc                 C   s  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dtjj|d  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rdd |jD |d< ndd |jD |d< n(|jr|jj	|d< d	|_|jdd nq| | q|sfd	S t |ddd }tdt| d! td"| d	S )#u   
        Отправляем учетки в аккаунт
        https://bcrm.carbonsoft.ru/project/Document/DOC-003025#spec-0-ldap
        ZANDrU   
user_localrY   Tservicedesk_allowrc   !=Nr   Zcmf_modified_at>u   Синхронизируем r3   zrg_member_of.ext_idcmf_deletedr   deleted_loginr8   r   	ext_loginzrg_member_of.systemr3   r2   include_deleted)rc   r   r8   r4   rN   r   r   	old_loginZ	only_datac                 S   s   g | ]}|j r|jjqS r-   )systemr6   r   .0objr-   r-   r.   
<listcomp>o  s      z/CmfPerson.account_sync_push.<locals>.<listcomp>rN   c                 S   s   g | ]}|j jqS r-   )r6   r   r   r-   r-   r.   r   q  s     )Zeva_app_tokenusersZrpc_account_sync_push)r,   methodu    учетокzauth/sync_accounts)r]   rQ   debugr$   r   countr\   r   rc   r   r   r8   r4   r   r   r   ro   r   r   Zonly_system_grp_syncrN   r   Zgen_eva_app_tokenr   Zcall_eva_account)r?   account_sync_lastforce_filterr   personrN   datar-   r-   r.   account_sync_pushN  sZ    


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   rY   TrP   r:   r8   rZ   r7   r8   r   u   Обработано u-   </br> Не удалось настроить:z</br>u)   Закончили настройку 2FA)r5   )r$   r   r\   rP   CmfAuthTwoFactorr:   r8   r   ro   commit_with_event	ExceptionZrollback_purge_eventr]   rC   rQ   r   rD   rp   Zadmin_alert)	r   r   r+   r,   Zfail_personZcntr   er5   r-   r-   r.   init_2fa_settings  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)rQ   r   Z
global_varZaccount_sync_statusr   Zager#   r   Zset_nowro   r   r$   r   r   r   logging	exceptionr   )r   r   r   r-   r-   r.   account_sync_users  s,    





zCmfPerson.account_sync_users)slicer2   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_typerY   Zpfeedr   zparent.is_defaultrZ   c                 S   s   g | ]}|j jqS r-   )rI   r   )r   r   r-   r-   r.   r     s     z-CmfPerson.pfeed_post_list.<locals>.<listcomp>Zperson_viewsz
NOT EXISTS	person_idr   rU   cache_status_typer   ZOPENrX   listsrW   c                 S   s   | j S rr   rH   xr-   r-   r.   <lambda>      z+CmfPerson.pfeed_post_list.<locals>.<lambda>r   c                 S   s   | j S rr   rH   r   r-   r-   r.   r     r   z-status_in_progress_start-cmf_created_at)r3   r2   r   r   )r$   ZCmfListr\   r   
isinstancer   r[   
is_defaultr]   rI   Zall_relation_personsCmfTaskr   rQ   rR   map)r*   r   r2   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   rI   )r*   Zobj_idrS   r,   r@   r-   r.   r     s    zCmfPerson.mark_viewedc                 O   s   d S rr   r-   r)   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-   rH   r   r-   r-   r.   r     s     z.CmfPerson.create_p2p_chats.<locals>.<listcomp>rV   rW   p2prZ   c                 S   s   g | ]}|j r|qS r-   )r   r   r-   r-   r.   r     s      rN   rI   zNOT INrG   Tr   )rN   r   r$   ru   
user_grouprI   ZCmfChatGroupr\   r   rV   r   ro   r]   Ztopics)r*   r   Zusr_grpZ	cur_chatsr   r   r}   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   rQ   rR   rI   r#   r$   r%   r&   rs   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>   r\   )r?   r   r   r+   r,   r@   r-   r.   r\     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   r$   CmfPersonVarrz   r   r=   restorer#   ro   )r*   Z
deleted_pvr-   r-   r.   _check_person_var  s    zCmfPerson._check_person_varc                 C   sF   | j s| jjsd S | jddrBtj }| j|jdsB| j| d S )NAdminsr~   )	is_newrN   r   r   r$   ru   Zcontact_admins_groupr6   r]   )r*   Zcontact_admin_groupr-   r-   r.   _calc_contact_admin#  s    
zCmfPerson._calc_contact_adminc                 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   )typer4   )r   r   companyr   oldnewr   loadr#   r   r$   Z
CmfCompanyrg   ro   )r*   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)r   r   rQ   rR   rn   
person_varZ	favoritesro   )r*   r   Zcurrent_person_varr-   r-   r.   _calc_default_favorites9  s    
z!CmfPerson._calc_default_favoritesc                 C   s   | j r| jsd S d S rr   )r   r   rs   r-   r-   r.   _calc_avatarF  s    zCmfPerson._calc_avatarc                    s:   t   ddddddddd	d
ddddddddddddg S )Nrc   notify_email
notify_smsr7   r:   rolesprimary_rolezcompany.typer   r   r   rM   r   r   rb   rd   re   r8   r   ztwo_factor.two_factor_optr   )r>   save_preload_fieldsrs   r@   r-   r.   r  L  s0                     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responsiblerY   r   r   CLOSEDr   z	<a href="z">z</a>z<br>z</a> uM   Обработайте задачи уволенного сотрудника)r  r4   r5   )r   r   r$   r   r\   r]   Zhrefr4   rD   get_supervisorro   )r*   Zlinkstaskr5   r-   r-   r.   _check_does_not_workT  s    

zCmfPerson._check_does_not_workc                 C   s"   t jj| jdgd}|r|jS d S )Nfail_block_end_daterc   r2   )r$   CmfAuthrz   rc   r  r*   authr-   r-   r.   r
   f  s    z&CmfPerson.get_auth_fail_block_end_datezdatetime.datetime | None)r   c                 C   s&   t jj| jd}|r"||_|  d S Nrc   )r$   r
  r=   rc   r  ro   r*   r   r  r-   r-   r.   r   k  s    z&CmfPerson.set_auth_fail_block_end_datec                 C   s"   t jj| jdgd}|r|jS d S )Nfail_permanent_blockr	  )r$   r
  rz   rc   r  r  r-   r-   r.   r   q  s    z'CmfPerson.get_auth_fail_permanent_blockboolc                 C   s&   t jj| jd}|r"||_|  d S r  )r$   r
  r=   rc   r  ro   r  r-   r-   r.   r   v  s    z'CmfPerson.set_auth_fail_permanent_blockc                    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)headr$   r   r=   rn   rj   )Zorg_unit	recursionr-   r.   r    s    
z+CmfPerson.get_supervisor.<locals>.recursionzprimary_role.supervisor.personzprimary_role.tree_parent.headNr   )rn   r  
supervisorr   rj   r$   ru   Zadmin_group
rg_membersr   r   )r*   r  Z	admin_grpr-   r  r.   r  |  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   )rN   r   rn   Zincompatible_combination_coderC   r   rf   r#   )r*   ZcodesZgrZgr_coder-   r-   r.   %_check_roles_incompatible_combination  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   )r*   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   r$   CmfAuthPluginDatar   r\   dirtyro   )r*   	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=   r#   r>   update)r*   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   rQ   r   r   rP   rK   r$   r   r:   r8   rs   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   )rN   r   r   r   r   r   rP   r$   r   r:   r8   ro   )r*   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 rr   )rc   r6   r   _calc_servicedesk_allowr>   _save_importr)   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/   Fr   r6   rY   ZProjectAdminsr   u  Изменение членства в группах на карточке пользователя для Проектных администраторов временно недоступно. Откройте группу и добавьте пользователя там.Tr   )rN   r   rQ   Zdisable_permissionsZacl_admin_moderR   rK   r$   r%   r&   ru   r=   rI   r   r|   r#   )r*   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   r8   r7   r9   r:   r;   r<   
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/   ra   r4   r5   )rn   Zfull_search_fieldsr   r$   ZCmfFullSearchZ
mark_cleanrI   r   Z
cmf_hiddenr4   rc   r8   rf   r   r  r>   full_search_index)r*   r,   Ztext_fieldsr4   r5   frr@   r-   r.   r*    sf                     	



zCmfPerson.full_search_indexc                 C   sp   | j jsdS tjjdddgdgdD ]F}| j|jjdr$ddd	gd
ddgdd|jgg}tj	j
|ddid q$dS )u   
        Для новых пользователей или при смене группы надо проверить нет ли его в АД
        N
sync_groupr   zsync_group.coderZ   r   r  rY   Fr   auth_pluginT)r3   values)rN   r   r$   ZCmfAuthLdapPluginslistr   r-  r6   rI   r  Zbulk_update)r*   pr   r-   r-   r.   _check_ad_grp-  s     
zCmfPerson._check_ad_grpc                    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 |   |   |s|   |   |   |   |   | jjr2t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sR| j#jrt$j%j&ddsntddd tj'j(| jd}|st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r2tj/j0ddrn*t$j%| 1 krntd| 1  ddd | j+s| j2jrt$j3s| j2rbtj45|  n*| jD ]"}tj46|rhtj47| | qht8t9| j*||}| :  | j;s| j<rt=tj9j> | ?  | j+rtj@| d}|*  |S )Nu   Для включения SMS уведомлений необходимо указать номер мобильного телефонаTr   Zperm_updater   r(  r   r  c                 S   s   g | ]
}|j qS r-   r6   r   rQ   r-   r-   r.   r   j  s     z"CmfPerson.save.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r-   r3  r4  r-   r-   r.   r   k  s     )r   r   )	r   r   r   r   r    r!   parent_nameparent_codeZ
audit_dataFalseZIBAdminsr   u   Изменять настройки паролей разрешено только Администраторам ИБ из группы IBAdminsr  uG   Пользователь не синхронизирован с accountr   r   )r   Fr   uw   Поле может редактировать только Администратор или Руководитель(rx   )r   )Ar&  r  r   r   r   rc   r6   r   r   r   r   r  r   r   r   r:   numberr7   r#   r  r#  r  r   r"  r2  r   rN   r$   r'   r(   r4   r   configZEVA_ACCOUNT_USEZpassword_must_changeZpassword_changed_daterQ   r{   r   r
  r=   Zpassword_expires_must_changero   r   ZcalendarZCmfCalendarno_staff_control_todayr%   r&   r  r    license_disable_user_count_hooks
CmfLicenserelease_all_user_licensesZis_license_groupZtake_user_licenser>   r   r   r   r   schedule_deferred_jobr   _check_notify_opt_cache_reloadZCmfTimeTracker)r*   Z	from_ldapr+   r,   r  r}   r   Zperson_timetrackerr@   r-   r.   ro   ;  s    





zCmfPerson.savec                    s  |  dtjj  tjjdd| gdgd}|rJtd| d	d
d d S | jrxdt	j	
 d }| d| j | _|   tjstj|  |drtjj| d
dD ]}|j|| qtjj| dD ]}|j|| qt j|| ttj| jjgd ttj tj  d S )Nrk   r   r)  r   rY   r.  rZ   u;   Пользователь синхронизирован с u9   , сначала отключите интеграцию.Tr   ZDELz%Y%m%d%H%M%Sra   ZTEXKOM_db_deleter   r   r+   )rk   r   r)  )rn   r$   r<  ZPERSON_LIC_FIELDSr/  r  r=   r#   r)  r   nowstrftimer   rQ   r;  r=  ZCmfPersonViewr\   deleter   r>   r>  r   sync_person_task_resourcesrI   r   r   ZCmfProjectNotifySchemeZtrigger_reload)r*   r+   r,   r  prefixr1  varr@   r-   r.   rC    s4         


zCmfPerson.deletec                    s8   | j rt| jd| j j| _ t j|| ttj	 d S rB   )
r)  resubZdelete_prefix_patternr   r>   r   r>  r   r   r)   r@   r-   r.   r     s    zCmfPerson.restorec                 C   sP   |rLt  }||d | }tj d| d}tj	|sLt
| |S )Nutf8/)hashlibmd5r  encode	hexdigestr*   _AVATAR_DIRECTORYospathexistsmakedirs)r?   rc   mZavatar_hashavatar_directoryr-   r-   r.   
avatar_dir  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 )Nr@  )r$   r   rV  rc   r   rP  rQ  isdirlistdirisfileremover>  set_gravatarrI   )r*   r+   r,   rU  filefilepathr-   r-   r.   r     s    zCmfPerson.remove_avataruV   Пересчет ресурсов после удаления пользователяr   )descriptionpriorityc                 C   sj   t jjdd| gdgdd}|rf|jrfdddgd	d
d| gdd| gggg}t jj|dD ]}t j| qTd S )NrI   rY   r   Tr   r   r   r  rU   r  rV   rW   r   )r$   r   r=   r   r   r\   ZCmfTaskResAssignZsync_task_resources)r   r   r   r  r-   r-   r.   rD    s    
z$CmfPerson.sync_person_task_resourcesu<   Регистрация нового пользователя)r   r^  show_bg_progressbar)guest)emailsc                O   s  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	 | }|rg }ntj g}| 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&d'gd(}|s,td) tj*|||| d*}n<|D ]*}td+|j+ d,|  |j,-| q0|shd|_t./  |0  W 5 Q R X |-|j1j td- q|S ).u   
        Регистрируем новых пользователей по email
        :param emails:
        :param guest:  пригласить как гостей
        :return:
        r   )sessionz/custom/org_namezCregister_persons: WARNING: org_name is not set, can't invite peopleZAllowInviter   Zuser_inviter   Nr   Tr   )r   r   r   r   r    r!   r5  r6  u.   Операция не доступна для r(  r   i:	 Zguid)rc   ZissZiatZexpZjtirH  zregister_persons:frominvite_must_change_password)r2   rw   Zinvite_by_email)r8   actioninvite_tokenre  )absoluteZinternalzauth/signup   )r   cookiestimeout,    zSigned up successfullyuE   ERROR: Не удалось отправить приглашение z: r6   rY   u"   Ищем пользователя rN   r   rZ   u)   Создадим пользователя)rc   r8   rN   r   u(   Добавим пользователя u    в группу z!register_persons: person saved ok)2Zrequestsrc  rP  rQ  rR  r9  PROJECT_DIRrQ   r   rR   rK   r{   r   rO   r   Zallow_user_inviter   r$   r'   r(   ZCmfPermissionErrorru   r   r   ZAPP_FQDNrC   inttimer8   r   Z
create_jwtZrsa_sign_pack_jwtZCmfGlobalSettingsr=   re  ZpostZauth_base_hrefrequestrj  status_coder5   Zjsonr   r4   rN   r]   rp   rq   ro   rI   )rb  ra  r+   r,   rc  r^   r8   sgroupsZpayloadZjwtrg  re  r   r   r   r   r}   r-   r-   r.   r     s    	


    

     


zCmfPerson.register_persons)r2   c                O   s   dg}| j |d|i|}|S )Navatar_filenamer2   rJ   )r?   r2   r+   r,   r   r-   r-   r.   r   F  s    zCmfPerson.public_get)r2   r3   c                O   s   d S rr   r-   )r?   r2   r3   r+   r,   r-   r-   r.   r   N  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   )r3   r   r   )r4   )
r7   r$   ZCmfDealr\   rI   r4   r   ZcontactsZprimary_contactro   )r*   r+   r,   ZdealsZdealr-   r-   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   rY   rL   rZ   Z	invisibleZoffline)Zjs_idr4   r/   )rL   Z
is_defined_valuer$   r   r=   rI   r   rQ   rR   choicesr   )r*   r   r4   r-   r-   r.   _online_statuse  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   rY   r   r   Zis_internalTruerN   rU   r   Fr6   r   r   ZUsers)object_fields	object_idr3   )r=   r>   field_options_list)r?   Zrelation_field_namerz  r{  r3   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   Ищем пользователя по номеру r7   r9   r:   r;   r   ZRUr   Nz;%rU   ZLIKErY   rZ   u.   Возвращаем пользователя %   Неправильный номер: )rQ   r   phonenumbersparseZformat_numberZPhoneNumberFormatZE164r$   r   r=   r   )	r?   r7   r2   r3   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 )NrI   rW   tree_parent_idr  rZ   r   )r$   Z
CmfOrgUnitr0  rI   insertr  )Zou_idsZou_ids_nextZouquery_our-   r.   r    s    z.CmfPerson.get_org_units_list.<locals>.query_ou)rn   r   r  r   r]   )r*   rS   rT   r^   Zou_ids_firstr,  Zou_listr-   r  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:   Создаем пользователя с номером )r7   r4   r}  rl  u@   Возвращаем пользователя с номером )r  rQ   r   r$   r   ro   r   r7   )r?   r7   r2   r3   r   r   r-   r-   r.   get_or_create_by_phone  s    z CmfPerson.get_or_create_by_phonec                 C   s2   t t|dd  j|d}|| jj| dS )u3   
        Позвонить клиенту
        :r   rH   N)varsr$   r   r=   callbackr7   Znumber_e164)r*   Z
channel_idr  channelr-   r-   r.   
phone_call  s    zCmfPerson.phone_callc                 O   s0   t j| jst | j t| j d| S )NrJ  )rP  rQ  rR  rO  rS  pathlibPath)r*   
image_hashr+   r,   r-   r-   r.   avatar_path  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   r@  rI  z.jpegwb)ru  r   r  rR  unlinkro   r>  r   r[  rI   r   r   rC   base64Zurlsafe_b64decoderK  rL  rc   rM  rN  openwrite)r*   image
image_typer[  r+   r,   r  Z
image_datar  Z
image_pathZ
image_filer-   r-   r.   r     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: не задан логинNrI  Zqwez https://www.gravatar.com/avatar/z/avatar.jpg?d=z&s=200r   )rk  u.   Ошибка запроса к gravatar {}: {}rm  )rc   rQ   r   rK  rL  r  r   lowerrf   rM  rN  rp   Zrequests_sessionr=   rq  r+   r   r   r   formatrr  r   Zcontent)r*   rT  defaulturlr   r   r-   r-   r.   fetch_gravatar  s     

zCmfPerson.fetch_gravatar<   u   Установка gravatar)r   Zsoft_time_limitr^  r`  c                 K   s<   t jj| d}|t j| | }|j|ddd d S )NrH   ZjpegF)r  r[  )r$   r   r=   rn   r  r  r   )r   rT   r   r  r-   r-   r.   r[    s    zCmfPerson.set_gravatarc                 O   s   d S rr   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ServiceDeskClientr3  TFu   Нельзя снять опцию у пользователя, т.к. она активирована через Проектную роль или включена глобальная опция "Разрешить доступ всем"r   rN   )rn   r   r   rN   r$   ru   r=   r   r   r   rQ   r   Zservicedesk_allow_auth_guestsr   r#   r]   rZ  )r*   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_osr7   r:   r4   r8   rc   r   r   )rI   r   r2   u8   Пользователь не существует (ID: rx   NuV   Пользователь удален или не работает(уволен) (ID: )r  r  r  r  r  r  r   r   r  r7   r:   r4   r8   rc   )r   cache_person_notify_optr$   r   r=   r#   r   r   rQ   r   r  r   r  r  r  r  r  r   r   r  r7   r8  r:   r4   r8   rc   )r?   r   r   r-   r-   r.   get_notify_opt_cachedD  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  r7   r:   r4   r8   rc   printrI   r   cmf_emit_server_eventr*   r   r-   r-   r.   r?  z  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  )r  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)rT   r   r   r-   r-   r.   on_person_notify_opt_change  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   r2   )Ztz)r$   r   r=   r  rA  r   timezoneZutcr*   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_counterrQ   r   Zauth_fail_try_countZauth_fail_permanent_blockr   rA  Z	timedeltaZauth_fail_timeoutr   Zauth_fail_block_end_datero   rs   r-   r-   r.   auth_fail_hook  s    
zCmfPerson.auth_fail_hookc                 C   s   d| _ | jdd d S )Nr   Tr   )r  ro   rs   r-   r-   r.   auth_success_hook  s    zCmfPerson.auth_success_hookc                 C   s&   |  ddg | jD ]}|  qd S )Nzperson_var.browser_timezonez,person_var.person.staff_control_blocked_date)rn   r   Zget_overdue_deadline_tasksr  r-   r-   r.   calc_staff_control_blocked  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)r$   r   r\   r:  ro   r   r-   r-   r.   %cron_drop_no_staff_control_today_flag  s    z/CmfPerson.cron_drop_no_staff_control_today_flagc                 C   sF   |  ddg d}| jD ](}|jr|jjs,q|jj
 d |j }q|S )u0   
        Ставка за минуту
        zroles.job.rate_per_hourz
roles.rater   r  )rn   r   ZjobZrate_per_hourrate)r*   r  r   r-   r-   r.   rate_per_minute  s    
zCmfPerson.rate_per_minute)T)N)NNN)NN)NNN)N)N)F)r   )N)N)NNN)NN)NN)NNT)F)___name__
__module____qualname__r9  rn  rO  r   r   Zapi_methodsr   classmethodr   rF   rK   r   r   propertyrg   r   rt   r   r   r   r   r   r   r   r   r   staticmethodZcmf_deferred_jobr   r   r   r   r   r   r   r\   r   r   r   r   r   r  r  r
   r   r   r   r  r  r  r  r  r   r"  r$  r&  r*  r2  ro   rC  r   rV  r   rD  r   r   r   r   rx  r|  r  r	   r  r  r  r   r  r[  r   r#  r  r?  r  Zon_server_eventr  r  r  r  r  r  r  __classcell__r-   r-   r@   r.   r      s  


 


W4
!	

		
4g
	

\



8
5

	r   )r  rK  r  rp  r~  Zcmf.data_providers.baser   Zcmf.includer   Zmodules.person.fieldsr   r   r-   r-   r-   r.   <module>   s   