B
    f                 @   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                   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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	d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Ze	dd:d;Zeeddd<ddd=d>d?Zeeddd@dAddBdCZdddddddDdEdFZ  fdGdHZ!dIdJ Z"dKdL Z#dMdN Z$e	dddO fdPdQ
Z%dRdS Z&dTdU Z'dVdW Z(dXdY Z) fdZd[Z*d\d] Z+d^d_ Z,d`dadbdcZ-ddde Z.dfdadgdhZ/didj Z0dkdl Z1ddndoZ2dpdq Z3ddr fdsdt
Z4dudv Z5dwdx Z6 fdydzZ7dd|d}Z8 fd~dZ9 fddZ: fddZ; fddZ<e	dddZ=dd Z>eedddddmde%dddZ?e	ddddZ@e	dddddZAdd ZBedd ZCe	dԇ fdd	ZDe	dddZEdd ZFe	dddZGdd ZHdd ZIdddZJdd ZKeeddddddd ZLe	dd ZMdddZNe	dd ZOdd ZPe	dd ZQeeRdddd ZSdd ZTdd ZUdd ZVddĄ ZWeeddddAddǄ ZXddɄ ZY  ZZS )	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 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_assistant)r   r   r   )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_name/   s    zCmfPerson.reverse_namec             C   s   | j ddS )Nz.CmfPerson:00000000-0000-0000-0000-000000000001)id)r%   )r'   r+   r+   r,   system_person2   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)r2   r   )modelsr   r%   gcurrent_personr2   )r'   Zcreate_args_kwargsr+   r+   r,   r   6   s    zCmfPerson.get_current_userc             C   sH   g }x>t jjdddtjjggddtjjgg|dD ]}|| q2W |S )NOR	executorsINcmf_owner_idz==)r   r   )r9   
CmfProjectlistr:   r;   r2   append)r'   r   resultprojectr+   r+   r,   r   <   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)r0   r(   r)   rH   rJ   rK   r+   r+   r,   	full_nameD   s    

zCmfPerson.full_namec          	   O   sr   |  dg | jsltjd | dddd}|jdd || _t  |   W d 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)Znotifyu   Документ1)rP   rR   r   )load_fieldsrN   r9   Z	CmfFoldersavecmfutildisable_aclZCmfDocument)r0   r(   r)   Zfolderr+   r+   r,   r   K   s    

zCmfPerson.get_home_folderc             C   s   | j p| jp| jS )N)rM   rI   r    )r0   r+   r+   r,   gen_nameZ   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CmfPersonGroupz--r2   )r   r   )r   r   uX   Ошибка вызова in_person_group: не найдена группа (group_code=z, group_name=z, group=)FT)Zid_only)rU   get_obj_id_by_anyr9   rX   sgetr2   	cmf_alertr:   current_usercurrent_person__member_ofCmfAccessListZsubject_full_group_list)r0   group
group_codeZ
group_nameZgroup_idZ	member_ofr+   r+   r,   in_person_group]   s(    
zCmfPerson.in_person_groupc             C   s   | j |||dS )u   
        ! DEPRICATED
        ! Публичное API для bzPython
        Для обратной совместимости
        )rF   	role_coderole)in_project_role)r0   rF   rc   rd   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CmfProjectRolez--r2   )r   r   )r   r   ug   Ошибка вызова in_project_role - не найдена Проектная роль (role_code=z, role_name=z, role=rY   FrB   )
rU   rZ   r9   rg   r[   r2   r\   valuer   get_project_role_members)r0   rF   rd   rc   Z	role_namerole_id
project_idr+   r+   r,   re      s     zCmfPerson.in_project_rolec             C   s   t j|t  t j| }||d  || }|d k	r>t|S t }xNtjjdd|gdd|ggddgdD ]&}x |j	 D ]}|
|jj qzW qjW |t j| |< t|S )Nparent=Zproject_rolemembersZproject_role_id)r   r   )APPZcache_in_project_role
setdefaultdictrC   setr9   ZCmfProjectRoleAssignrn   
all_nestedaddr2   rh   )r'   rk   rj   Zproject_cacheZrole_cache_setZrulememberr+   r+   r,   ri      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 )Nr5   vacation_startvacation_endFT)rS   rv   rw   datetimeZutcnowZdater5   )r0   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   rG   r         )r   
is_changedis_nullrh   replaceVACATION_SUFFIXDOES_NOT_WORK_SUFFIXrL   splitlenrH   rJ   rK   )r0   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 )Nr   rG   )r   r|   rJ   rK   rH   rI   r5   does_not_workr   r   rM   )r0   Zadd_strr+   r+   r,   
_calc_name   s    zCmfPerson._calc_namec             C   sr   t tjjjtjjjtjjjtjjjd}| jrXx(|D ] }| jj	|r4| j| ||< q4W |d sn| j
rnd|d< |S )N)
allow_baseZ
allow_ldapZallow_oauthZ	allow_ssor   T)rq   r:   global_settingsZauth_options_allow_baserh   Zauth_options_allow_ldapZauth_options_allow_oauthZauth_options_allow_ssoauth_optionsr%   r7   )r0   reskeyr+   r+   r,   get_auth_options,  s    

zCmfPerson.get_auth_optionsc             C   sn  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 }xt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rv|jj|d< d	|_|jdd nqv| | qvW |sNd	S t |ddd}td| d	S ) u   
        Отправляем учетки в аккаунт
        https://bcrm.carbonsoft.ru/project/Document/DOC-003025#spec-0-ldap
        ZANDr>   
user_localz==Tservicedesk_allowrI   z!=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)rI   r   r    r   r6   r   r   	old_login)	only_datac             S   s   g | ]}|j r|jjqS r+   )systemr   rh   ).0objr+   r+   r,   
<listcomp>[  s    z/CmfPerson.account_sync_push.<locals>.<listcomp>r6   c             S   s   g | ]}|j jqS r+   )r   rh   )r   r   r+   r+   r,   r   ]  s    )Zeva_app_tokenusersZrpc_account_sync_push)r)   methodzauth/sync_accounts)rD   r9   r   rC   rq   rI   rh   r   r    r   r   r   r   rT   r   r:   r   Zonly_system_grp_syncr6   r   Zgen_eva_app_tokenZcall_eva_account)r'   account_sync_lastforce_filterr   personr6   datar+   r+   r,   account_sync_push;  sL    
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} xt jj| dddgdD ]}yF|jsXt j|j|jd	|_||j_|j  |  t	  |d
7 }W q8 t
k
r } z"t  |t| t| W d d }~X Y q8X q8W d| }|r| dd| }t| tjd|d d S )Nr   r   z==Tr8   r"   r    )r   r   )r   r    rz   u   Обработано u-   </br> Не удалось настроить:z</br>u)   Закончили настройку 2FA)r   )r9   r   rC   r8   CmfAuthTwoFactorr"   r    r   rT   commit_with_event	ExceptionZrollback_purge_eventrD   r-   r:   debugr.   rU   Zadmin_alert)	r   r   r(   r)   Zfail_personZcntr   er   r+   r+   r,   init_2fa_settingsn  s.    
 

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
  y&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 dd}~X Y nX dS )
uz   
        Синхронизируем уровень доступа с accounts сервером
        :return:
        u6   Запуск синхронизации с eva_accountZin_progressi  u   Синхронизация пользователей зависла, запускаем форсированно повторноu2   Синхронизация уже запущенаN)r   closederror)r:   r   Z
global_varZaccount_sync_statusr   Zager\   rh   Zset_nowrT   r   r9   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   sR  t jjdddgddgd}	t }
xZ|	D ]R}|jrTt|jjt jrT|jjrT|
| q&| j	jdd |
 D kr&|
| q&W |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}|r6|| t jj||ddg|d}|S )NZ	list_typez==Zpfeedrl   zparent.is_default)r   r   c             S   s   g | ]}|j jqS r+   )r2   rh   )r   r   r+   r+   r,   r     s    z-CmfPerson.pfeed_post_list.<locals>.<listcomp>Zperson_viewsz
NOT EXISTS	person_idrm   r>   cache_status_typez!=ZOPENrA   listsr@   c             S   s   | j S )N)r2   )xr+   r+   r,   <lambda>      z+CmfPerson.pfeed_post_list.<locals>.<lambda>)r   c             S   s   | j S )N)r2   )r   r+   r+   r,   r     r   z-status_in_progress_startz-cmf_created_at)r   r   r   r   )r9   ZCmfListrC   rl   
isinstancerh   rB   
is_defaultrD   r2   Zall_relation_personsCmfTaskcountr:   r;   map)r0   r   r   r   r   r   r   r(   r)   r   Zmy_listsZlstZfltZ	post_listr+   r+   r,   r     s6    



 
zCmfPerson.pfeed_post_listc                s   t  j|fd| ji|S )Nr   )r&   r   r2   )r0   Zobj_idr<   r)   )r*   r+   r,   r     s    zCmfPerson.mark_viewedc             O   s   d S )Nr+   )r0   r(   r)   r+   r+   r,   public_mark_viewed  s    zCmfPerson.public_mark_viewedc             C   s
  g }| j jrtj }|jdd | j D krtjjdd| jggdgd}|r^dd |D }|sdd|jggd	d
d| jggg}xtjj|d	gdD ]l}t }|g|_	d|_
|  |j	|  |jdd x&|jD ]}|j	|  |jdd qW || qW |S )Nc             S   s   g | ]
}|j qS r+   )r2   )r   r   r+   r+   r,   r     s    z.CmfPerson.create_p2p_chats.<locals>.<listcomp>r?   r@   p2p)r   r   c             S   s   g | ]}|j r|qS r+   )r   )r   r   r+   r+   r,   r     s    r6   r2   zNOT INz.CmfPerson:00000000-0000-0000-0000-000000000001T)r   )r6   r|   r9   rX   
user_groupr2   ZCmfChatGrouprC   r   r?   r   rT   rD   Ztopics)r0   r   Zusr_grpZ	cur_chatsr   r   r`   Ztopicr+   r+   r,   create_p2p_chats  s.    

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   r:   r;   r2   r\   r9   r_   check_admin_mode)r0   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   )rp   r&   rC   )r'   r   r   r(   r)   )r*   r+   r,   rC     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   r9   CmfPersonVarr[   r   r%   restorer\   rT   )r0   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?   Контакт не может быть без компанииT)r   )typer   )r   r   companyr|   oldnewr   loadr\   r}   r9   Z
CmfCompanyrM   rT   )r0   Znew_companyr+   r+   r,   _calc_company  s    "zCmfPerson._calc_companyc             C   sT   | j r| jsdS tjdg x0| jD ]&}x tjjD ]}|j|_|  q4W q&W dS )u   
        Вычисляем список избранного по умолчанию для новых пользователей
        Nzperson_var.favorites)is_newr   r:   r;   rS   
person_varZ	favoritesrT   )r0   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 )N)r   r   )r0   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 )NrI   notify_email
notify_smsr   r"   rolesprimary_rolezcompany.typer   r   r   r5   rv   rw   rH   rJ   rK   r    r   ztwo_factor.two_factor_opt)r&   save_preload_fields)r0   )r*   r+   r,   r   .  s
    
zCmfPerson.save_preload_fieldsc             C   s   | j r| j jsdS g }xBtjjdd| gdddggdD ] }|d|j d	|j d
 q6W |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responsiblez==r   z!=ZCLOSED)r   z	<a href="z">z</a>z<br>z</a> uM   Обработайте задачи уволенного сотрудника)r   r   r   )r   r|   r9   r   rC   rD   Zhrefr   r.   get_supervisorrT   )r0   ZlinksZtaskr   r+   r+   r,   _check_does_not_work5  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)rI   r   )r9   CmfAuthr[   rI   r   )r0   authr+   r+   r,   r
   G  s    z&CmfPerson.get_auth_fail_block_end_datezdatetime.datetime | None)rh   c             C   s&   t jj| jd}|r"||_|  d S )N)rI   )r9   r   r%   rI   r   rT   )r0   rh   r   r+   r+   r,   r   L  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_block)rI   r   )r9   r   r[   rI   r   )r0   r   r+   r+   r,   r   R  s    z'CmfPerson.get_auth_fail_permanent_blockboolc             C   s&   t jj| jd}|r"||_|  d S )N)rI   )r9   r   r%   rI   r   rT   )r0   rh   r   r+   r+   r,   r   W  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)headr9   r   r%   rS   rP   )Zorg_unit)	recursionr+   r,   r   a  s    
z+CmfPerson.get_supervisor.<locals>.recursionzprimary_role.supervisor.personzprimary_role.tree_parent.headNr   )rS   r   
supervisorr   rP   r9   rX   Zadmin_group
rg_membersr   rs   )r0   r   Z	admin_grpr+   )r   r,   r   ]  s    	

zCmfPerson.get_supervisorc          	   C   s   | j jsd S i }| dg xl| j D ]b}|js0q$xTt|jdD ]@}| }||krztd||  d| d| dd qB|||< qBW q$W d S )Nz*rg_member_of.incompatible_combination_code,u\   Пользователь не может участвовать одновременно в u    и uS   , так как у них указан Код запрета совмещения: T)r   )r6   r|   rS   Zincompatible_combination_coder-   r   rL   r\   )r0   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}   )r0   r   r+   r+   r,   _calc_primary_role  s    zCmfPerson._calc_primary_rolec             C   sF   | j rtjj| dsdS x(tjj| dD ]}d|_|jdd q(W dS )uN   Надо пометить что данные не засинканы
        )r   NT)r   )r|   r9   CmfAuthPluginDatar   rC   ZdirtyrT   )r0   	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   Назначение или открепление должности пользователю необходимо производить в "Структуре" в карточке должностиT)r   r   )r%   r\   r&   update)r0   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 )N)r   r    )
r   r:   r   r   r8   r3   r9   r   r"   r    )r0   r+   r+   r,   
_check_2fa  s     zCmfPerson._check_2fac             C   sr   | j jsd S d }x$| j jD ]}|j r|jj}P qW |s>d S | jsXtj| j	| j
d| _|| j_| jjdd d S )N)r   r    T)r   )r6   r|   r   r   r   rh   r8   r9   r   r"   r    rT   )r0   r   Zgrpr+   r+   r,   _check_2fa_group  s    
zCmfPerson._check_2fa_groupc                s<   | j r| j| j kr| j | _|   |   t j|| d S )N)rI   r   r   _calc_servicedesk_allowr&   _save_import)r0   r(   r)   )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)raise_errorr   z==ZProjectAdmins)r   u  Изменение членства в группах на карточке пользователя для Проектных администраторов временно недоступно. Откройте группу и добавьте пользователя там.T)r   )r6   r|   r:   Zdisable_permissionsZacl_admin_moder;   r3   r9   r_   r   rX   r%   r2   rh   r^   r\   )r0   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}x|D ]}|dkr*x| jD ]"}|j	jr|d|j	j 7 }qW q|dkr^| jr|| jj	jr||d| jj	j 7 }q| | jr|d| | j 7 }qW ||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   rG   r   r   )rS   Zfull_search_fieldsr   r9   ZCmfFullSearchZ
mark_cleanr2   rh   Z
cmf_hiddenr   rI   r    rL   r   r   r&   full_search_index)r0   r)   Ztext_fieldsr   r   fr)r*   r+   r,   r     sB    




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 уведомлений необходимо указать номер мобильного телефонаT)r   Zperm_updater   r   r{   r   c             S   s   g | ]
}|j qS r+   )r   )r   r:   r+   r+   r,   r   9  s    z"CmfPerson.save.<locals>.<listcomp>c             S   s   g | ]
}|j qS r+   )r   )r   r:   r+   r+   r,   r   :  s    )r   r   )	operatecmf_model_namerl   result_statuscurrent_transactionsecurity_levelparent_nameparent_codeZ
audit_dataFalseZIBAdmins)ra   u   Изменять настройки паролей разрешено только Администраторам ИБ из группы IBAdmins)rI   uG   Пользователь не синхронизирован с accountrz   )r   )r   F)r   uw   Поле может редактировать только Администратор или Руководитель(rY   )rl   )9r   r   r   r|   r   rI   r   ry   r   r   r   r   r   r   r   r"   numberr   r\   r   r   r   r   r   r6   r9   CmfAuditaudit_eventr   r   configZEVA_ACCOUNT_USEZpassword_must_changeZpassword_changed_dater:   r]   rb   r   r%   Zpassword_expires_must_changerT   r   ZcalendarZCmfCalendarno_staff_control_todayr_   r   r   r&   r   r   r   r   schedule_deferred_jobr   _check_notify_opt_cache_reloadZCmfTimeTracker)r0   r(   r)   r   r   Zperson_timetracker)r*   r+   r,   rT     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rx$tj
j| d
dD ]}|j|| qW x"tjj| dD ]}|j|| qW t j|| ttj tj  d S )NrQ   r   r   r   z==Zauth_plugin)r   r   u;   Пользователь синхронизирован с u9   , сначала отключите интеграцию.T)r   ZDELz%Y%m%d%H%M%SrG   ZTEXKOM_db_delete)r   r   )r   )rS   r9   r   r%   r\   r   rx   nowZstrftimer   ZCmfPersonViewrC   deleter   r&   r  r   r   ZCmfProjectNotifySchemeZtrigger_reload)r0   r(   r)   r   prefixpvar)r*   r+   r,   r
  i  s"    

zCmfPerson.deletec                s8   | j rt| jd| j j| _ t j|| ttj	 d S )Nr   )
r   resubZdelete_prefix_patternrh   r&   r   r  r   r   )r0   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	hexdigestr0   _AVATAR_DIRECTORYospathexistsmakedirs)r'   rI   mZavatar_hashavatar_directoryr+   r+   r,   
avatar_dir  s    
zCmfPerson.avatar_dirc             O   sj   t j| jj}tj|rRx4t|D ]&}| | }tj	|r(t
| q(W ttj| jjgd d S )N)r(   )r9   r   r  rI   rh   r  r  isdirlistdirisfileremover  set_gravatarr2   )r0   r(   r)   r  filefilepathr+   r+   r,   r     s    zCmfPerson.remove_avataru<   Регистрация нового пользователя)r   description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sx(| D ] }tjjddd	d
dd||d qhW tdtj	 | }|rg }ntj g}x| 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(}|s4td) tj*|||| d*}n@x2|D ]*}td+|j+ d,|  |j,-| q:W |std|_t./  |0  W d	Q R X |-|j1j td- qW |S ).u   
        Регистрируем новых пользователей по email
        :param emails:
        :param guest:  пригласить как гостей
        :return:
        r   )sessionz/custom/org_namezCregister_persons: WARNING: org_name is not set, can't invite peopleZAllowInvite)ra   Zuser_inviter   NZfailTr{   )r   r   rl   r   r   r   r   r   u.   Операция не доступна для r   rz   i:	 Zguid)rI   ZissZiatZexpZjtir  zregister_persons:frominvite_must_change_password)r   Zcache_inmemoryZinvite_by_email)r    actioninvite_tokenr+  )ZabsoluteZinternalzauth/signup   )r   cookiestimeoutz,    zSigned up successfullyuE   ERROR: Не удалось отправить приглашение z: r   z==u"   Ищем пользователя r6   r   )r   r   u)   Создадим пользователя)rI   r    r6   r   u(   Добавим пользователя u    в группу z!register_persons: person saved ok)2Zrequestsr)  r  r  r  r  PROJECT_DIRr:   r   r;   r3   r]   r   r7   r   Zallow_user_inviterb   r9   r  r  ZCmfPermissionErrorrX   r   rq   ZAPP_FQDNr-   inttimer    rh   Z
create_jwtZrsa_sign_pack_jwtZCmfGlobalSettingsr%   r+  ZpostZauth_base_hrefrequestr/  status_coder   Zjsonr   r   r6   rD   rU   rV   rT   r2   )r(  r'  r(   r)   r)  rE   r    sgroupsZpayloadZjwtr-  r+  r   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 )Nr+   )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_idrm   z-cmf_created_at)r   r   r   )r   )
r   r9   ZCmfDealrC   r2   r   r   ZcontactsZprimary_contactrT   )r0   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   z==r4   )r   r   Z	invisibleZoffline)Zjs_idr   r   )r4   Z
is_definedZ_valuer9   r   r%   r2   r   r:   r;   choicesrh   )r0   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   z==r   r   Zis_internalTruer6   r>   r   Fr   rm   ZAdminsZUsers)object_fields	object_idr   )r%   r&   field_options_list)r'   Zrelation_field_namer=  r>  r   r)   )r*   r+   r,   r?  &  s    "zCmfPerson.field_options_listc       	   
   C   s   t d|  |s"dddddg}yt|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|  |S  t
k
r } zt d|  d	S d	}~X Y nX d	S )us   
        Ищем персону по номеру телефона
        :param phone:
        :return:
        u4   Ищем пользователя по номеру r   r!   r"   r#   r   ZRUrz   Nz;%r>   ZLIKEz==)r   r   u.   Возвращаем пользователя u%   Неправильный номер: )r:   r   phonenumbersparseZformat_numberZPhoneNumberFormatZE164r9   r   r%   r   )	r'   r   r   r   Z	phone_objZformat_phoner   r   r   r+   r+   r,   get_by_phone9  s$    
zCmfPerson.get_by_phonec                s\   g }i }|  dg x.| jD ]$}|jrg }|||jj< || qW  fdd  | |S )Nzroles.tree_parent_idc                s`   i }xJt jjdd| gddgdD ],}| |j d| |jr | |j ||j< q W |r\ | d S )Nr2   r@   tree_parent_idr   )r   r   r   )r9   Z
CmfOrgUnitZslistr2   insertrC  )Zou_idsZou_ids_nextZou)query_our+   r,   rE  ^  s     z.CmfPerson.get_org_units_list.<locals>.query_ou)rS   r   rC  rh   rD   )r0   r<   r=   rE   Zou_ids_firstr   Zou_listr+   )rE  r,   r	   S  s    	zCmfPerson.get_org_units_listc          
   C   s   | j |||d}|sxy*td|  tj||d}|  W n8 tk
rv } ztd| d|  d S d }~X Y nX td|j  |S )N)r   u:   Создаем пользователя с номером )r   r   u%   Неправильный номер: z, u@   Возвращаем пользователя с номером )rB  r:   r   r9   r   rT   r   r   )r'   r   r   r   r   r   r+   r+   r,   get_or_create_by_phonek  s    z CmfPerson.get_or_create_by_phonec             C   s2   t t|dd  j|d}|| jj| dS )u3   
        Позвонить клиенту
        :r   )r2   N)varsr9   r   r%   callbackr   Znumber_e164)r0   Z
channel_idrI  channelr+   r+   r,   
phone_cally  s    zCmfPerson.phone_callc             O   s0   t j| jst | j t| j d| S )Nr  )r  r  r  r  r  pathlibZPath)r0   
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 d Q R X | jdd d S )NT)r   )r(   r  z.jpegwb)r9  r   rN  r  unlinkrT   r  r   r"  r2   rh   r   r-   base64Zurlsafe_b64decoder  r  rI   r  r  openwrite)r0   image
image_typer"  r(   r)   rN  Z
image_datarM  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}yt j|tjdd	}W n4 tk
r } ztd
|| 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=200rz   )r0  u.   Ошибка запроса к gravatar {}: {}r1  )rI   r:   r   r  r  r   rh   lowerrL   r  r  rU   Zrequests_sessionr%   r5  r(   r   r   r   formatr6  r   Zcontent)r0   r  defaultZ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 )N)r2   ZjpegF)rU  r"  )r9   r   r%   rS   r   rY  r   )r   r=   r   rT  r+   r+   r,   r"    s    zCmfPerson.set_gravatarc             O   s   d S )Nr+   )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ServiceDeskClient)r   TFu   Нельзя снять опцию у пользователя, т.к. она активирована через Проектную роль или включена глобальная опция "Разрешить доступ всем")r   r6   )rS   r   r|   r6   r9   rX   r%   rr   r   r   r:   r   Zservicedesk_allow_auth_guestsr   r\   rD   r!  )r0   r   Zsdesk_groupr   r+   r+   r,   r     s8    


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    rI   r   r   )r2   r   r   u8   Пользователь не существует (ID: rY   NuV   Пользователь удален или не работает(уволен) (ID: )r[  r\  r]  r^  r_  r`  r   r   ra  r   r"   r   r    rI   )ro   cache_person_notify_optr9   r   r%   r\   r   r   r:   r   r[  rh   r\  r]  r^  r_  r`  r   r   ra  r   r  r"   r   r    rI   )r'   r   r   r+   r+   r,   get_notify_opt_cached  sP    



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   zCmfPerson:changed)r   r   r|   r   r[  r\  r]  r^  r_  r`  r   r   ra  r   r"   r   r    rI   printr2   rh   cmf_emit_server_event)r0   r   r+   r+   r,   r  .  s*    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   ALLzCmfPerson:changed)rd  re  )r0   r   r+   r+   r,   flush_all_notify_opt_cacheG  s    z$CmfPerson.flush_all_notify_opt_cachezCmfPerson:changed)rJ  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   rf  z%person_notify_opt_change::reload done)rd  r%   ro   rb  pop)r=   r   r   r+   r+   r,   on_person_notify_opt_changeM  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)r9   r   r%   rj  r	  rx   ZtimezoneZutc)r0   r   r+   r+   r,   get_current_datetimeY  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 )Nrz   T)Zminutesr   )r   )auth_fail_try_counterr:   r   Zauth_fail_try_countZauth_fail_permanent_blockrx   r	  Z	timedeltaZauth_fail_timeoutrh   Zauth_fail_block_end_daterT   )r0   r+   r+   r,   auth_fail_hookb  s    zCmfPerson.auth_fail_hookc             C   s   d| _ | jdd d S )Nr   T)r   )rl  rT   )r0   r+   r+   r,   auth_success_hookp  s    zCmfPerson.auth_success_hookc             C   s*   |  ddg x| jD ]}|  qW d S )Nzperson_var.browser_timezonez,person_var.person.staff_control_blocked_date)rS   r   Zget_overdue_deadline_tasks)r0   r   r+   r+   r,   calc_staff_control_blockedt  s    z$CmfPerson.calc_staff_control_blockedz@dailyc              C   s0   x*t jjdddgdD ]} d| _|   qW d S )Nr  rm   T)r   F)r9   r   rC   r  rT   )r   r+   r+   r,   %cron_drop_no_staff_control_today_flagz  s    z/CmfPerson.cron_drop_no_staff_control_today_flagc             C   sJ   |  ddg d}x2| jD ](}|jr|jjs.q|jj
 d |j }qW |S )u0   
        Ставка за минуту
        zroles.job.rate_per_hourzroles.r   rZ  )rS   r   ZjobZrate_per_hourrate)r0   rq  rd   r+   r+   r,   rate_per_minute  s    zCmfPerson.rate_per_minute)T)N)NNN)NN)NNN)N)N)F)r   )N)NNN)NN)NN)NNT)F)[__name__
__module____qualname__r  r2  r  r   r   Zapi_methodsclassmethodr   r1   r3   r   r   propertyrM   r   rW   rb   rf   re   ri   ry   r   r   r   r   staticmethodZcmf_deferred_jobr   r   r   r   r   r   r   rC   r   r   r   r   r   r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   rT   r
  r   r  r   r   r   r   r   r;  r?  rB  r	   rF  rK  rN  r   rY  r"  r   r   rc  r  rg  Zon_server_eventri  rk  rm  rn  ro  rp  rr  __classcell__r+   r+   )r*   r,   r      s   
 

W2
!	
		
4[
	\

86	r   )rQ  r  rL  r4  r@  Zcmf.data_providers.baser   Zcmf.includerx   Zmodules.person.fieldsr   r   r+   r+   r+   r,   <module>   s   