U
    do                     @   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ejdd  dS )    N)md5)	randrange)Random)post)commit_all_ds)*)BeautifulSoup)
cmf_personc                       s  e Zd Zej 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dZdddZdd Zdd Zd d! Zd"d# Zedd$d%Zed&d' Zeejddd(d)d* Zeejddd(dd+d,Zddddddd-d.d/Zd0d1 Zd2d3 Z d4d5 Z!d6d7 Z"eddd8 fd9d:
Z#d;d< Z$d=d> Z%d?d@ Z&dAdB Z' fdCdDZ(dEdF Z)dGdH Z*dIdJ Z+ddLdMZ,dNdO Z-eddPdQZ.edddRdSdTZ/ddU fdVdW
Z0dXdY Z1 fdZd[Z2 fd\d]Z3edd^d_Z4d`da Z5eejddbe#dcdddeZ6edfdg Z7eddhdidjZ8edddkdldmZ9dndo Z:edpdq Z;ed fdrds	Z<eddtduZ=dvdw Z>eddxdyZ?dzd{ Z@d|d} ZAdd~dZBdd ZCeejddddd ZDedd ZEdddZF  ZGS )	CmfPersonz/custom/static/avatar/ 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_2Zphone_assistantr   )getsupersearch)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 )N.CmfPerson:00000000-0000-0000-0000-000000000001idr   r   r    r    r!   system_person%   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r*   r   )modelsr
   r   gcurrent_personr*   )r   Zcreate_args_kwargsr    r    r!   get_current_user)   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   )r4   
CmfProjectlistr5   r6   r*   append)r   r   resultprojectr    r    r!   get_current_projects/   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   rH   rJ   rK   r    r    r!   	full_name7   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)rP   rR   r   )load_fieldsrN   r4   Z	CmfFoldersavecmfutildisable_aclZCmfDocument)r&   r   r   Zfolderr    r    r!   get_home_folder>   s     
zCmfPerson.get_home_folderc                 C   s   | j p| jp| jS N)rM   rI   r   r&   r    r    r!   gen_nameM   s    zCmfPerson.gen_namec                 C   s   |s|rt jj|d}|s,|r,t jj|d}|sPtd| d| d| d dS | tjkrbtj}nt jj| dd	}|j	j
|krdS dS )
u   
        ! Публичное API для bzPython
        Метод проверки, что пользователь находится в группе
        r   r   uX   Ошибка вызова in_person_group: не найдена группа (group_code=z, group_name=z, group=)FTZid_only)r4   CmfPersonGroupr   	cmf_alertr5   current_usercurrent_person__member_ofCmfAccessListsubject_full_group_listr*   value)r&   groupZ
group_codeZ
group_name	member_ofr    r    r!   in_person_groupP   s    
zCmfPerson.in_person_groupc                 C   s   | j |||dS )u   
        ! DEPRICATED
        ! Публичное API для bzPython
        Для обратной совместимости
        )rD   	role_coderole)in_project_role)r&   rD   rj   rk   r    r    r!   has_project_roleh   s    zCmfPerson.has_project_rolec                 C   s   |s|rt jj|d}|s,|r,t jj|d}|sPtd| d| d| d dS | tjkrbtj}nt jj| dd	}t j	j
d
d|jgddgdD ]N}|jr|jsq|j|krq|jD ](}|| kr  dS |jj|kr  dS qqdS )u   
        ! Публичное API для bzPython
        Метод проверки, что пользователь назначен на Проектную роль
        r\   r]   ug   Ошибка вызова in_project_role - не найдена Проектная роль (role_code=z, role_name=z, role=r^   FTr_   parent=membersproject_role.coder?   )r4   ZCmfProjectRoler   ra   r5   rb   rc   rd   re   CmfProjectRoleAssignrA   r*   rp   project_rolerf   )r&   rD   rk   rj   Z	role_namerh   rmemberr    r    r!   rl   p   s0    

 


zCmfPerson.in_project_rolec                 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)rT   rv   rw   datetimeZutcnowdater/   )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rf|d | _
t	|dkr||d | _t	|dkr|d | _d S )Nr   rG   r         )r   
is_changedis_nullrf   replaceVACATION_SUFFIXDOES_NOT_WORK_SUFFIXrL   splitlenrH   rJ   rK   )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 rF   )r   r}   rJ   rK   rH   rI   r/   does_not_workr   r   rM   )r&   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)dictr5   global_settingsZauth_options_allow_baserf   Zauth_options_allow_ldapZauth_options_allow_oauthZauth_options_allow_ssoauth_optionsr   r1   )r&   reskeyr    r    r!   get_auth_options  s    
zCmfPerson.get_auth_optionsc              
   C   sH  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| d}|j
s|jst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|s(d	S t |ddd}td| d	S ) u   
        Отправляем учетки в аккаунт
        https://bcrm.carbonsoft.ru/project/Document/DOC-003025#spec-0-ldap
        ZANDr:   
user_localr>   Tservicedesk_allowrI   !=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   Zinclude_deleted)rI   r   r   r   r0   r   r   c                 S   s   g | ]}|j r|jjqS r    )systemr   rf   .0objr    r    r!   
<listcomp>1  s      z/CmfPerson.account_sync_push.<locals>.<listcomp>r0   c                 S   s   g | ]}|j jqS r    )r   rf   r   r    r    r!   r   3  s     Z	only_data)Zeva_app_tokenusersZrpc_account_sync_push)r   methodz/auth/sync_accounts)rB   r4   r
   rA   r   rI   rf   r   r   r   r   r   r   r5   r   Zonly_system_grp_syncr0   r   rU   Zgen_eva_app_tokenZcall_eva_account)r   account_sync_lastforce_filterr   personr0   datar    r    r!   account_sync_push  sN    

zCmfPerson.account_sync_pushc                 C   s   t td t| j d S )Ni  )timesleepr   cmf_deferred_taskaccount_sync_usersr,   r    r    r!   cron_account_sync_usersD  s    z!CmfPerson.cron_account_sync_users)	only_onceZsystem_taskc                  O   s   g }d}t jjdddgddd ggdddgdD ]t}z.t j|j|jd	|_|  t  |d
7 }W q. t	k
r } z"t
  |t| t| W 5 d }~X Y q.X q.d| }|r| dd| }t| tjd|d d S )Nr   r   r>   Tr2   r   r   r?   r   r   r{   u   Обработано u-   </br> Не удалось настроить:z</br>u)   Закончили настройку 2FA)r   )r4   r
   rA   CmfAuthTwoFactorr   r   r2   rU   commit_with_event	ExceptionZrollback_purge_eventrB   r"   r5   debugr#   rV   Zadmin_alert)r   r   Zfail_personZcntr   er   r    r    r!   init_2fa_settingsI  s.    


zCmfPerson.init_2fa_settingsc              
   O   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)r5   r   Z
global_varZaccount_sync_statusr   Zagera   rf   Zset_nowrU   r   r4   r
   r   r   logging	exceptionr   )r   r   r   r   r   r    r    r!   r   a  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_typer>   Zpfeedrn   zparent.is_defaultr?   c                 S   s   g | ]}|j jqS r    )r*   rf   )r   r   r    r    r!   r     s     z-CmfPerson.pfeed_post_list.<locals>.<listcomp>Zperson_viewsz
NOT EXISTS	person_idro   r:   cache_status_typer   ZOPENr=   listsr<   c                 S   s   | j S rY   r)   xr    r    r!   <lambda>      z+CmfPerson.pfeed_post_list.<locals>.<lambda>r   c                 S   s   | j S rY   r)   r   r    r    r!   r     r   z-status_in_progress_start-cmf_created_at)r   r   r   r   )r4   ZCmfListrA   rn   
isinstancerf   r@   Z
is_defaultrB   r*   Zall_relation_personsCmfTaskcountr5   r6   map)r&   r   r   r   r   r   r   r   r   r   Zmy_listsZlstZfltZ	post_listr    r    r!   pfeed_post_list  sB    


 
zCmfPerson.pfeed_post_listc                 O   sP   | j tjj kr(| j tjj kr(tddd tjj| j |dsLtj| |d  d S )NzKDEV: FATAL self.id != g.current_person.id and self.id != g.system_person.idTabort)r   obj_id)r   r   )	r*   r5   r6   r-   ra   r4   ZCmfPersonViewr   rU   )r&   r   r   r   r    r    r!   mark_viewed  s    zCmfPerson.mark_viewedc                 O   s   d S rY   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    r)   r   r    r    r!   r     s     z.CmfPerson.create_p2p_chats.<locals>.<listcomp>r;   r<   p2pr?   c                 S   s   g | ]}|j r|qS r    )r   r   r    r    r!   r     s      r0   r*   zNOT INr(   Tr   )r0   r}   r4   r`   
user_groupr*   ZCmfChatGrouprA   r
   r;   r   rU   rB   Ztopics)r&   r   Zusr_grpZ	cur_chatsr   r   rg   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   Нельзя удалить самого себяTr   )r   r5   r6   r*   ra   r4   rd   Zcheck_admin_moderZ   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   )
setdefaultr   rA   )r   r   r   r   r   r   r    r!   rA     s
    zCmfPerson.listc                 C   s$   | j r| jrd S tj| d  d S )Nr   )r   
person_varr4   CmfPersonVarrU   rZ   r    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   loadra   r~   r4   
CmfCompanyrM   rU   )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)is_newr   r5   r6   rT   r   Z	favoritesrU   )r&   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 rY   )r   r   rZ   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   Znotify_email
notify_smsr   r   rolesprimary_rolezcompany.typer   r   r   r/   rv   rw   rH   rJ   rK   r   r   r2   )r   save_preload_fieldsrZ   r   r    r!   r     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responsibler>   r   r   ZCLOSEDr   z	<a href="z">z</a>z<br>z</a> uM   Обработайте задачи уволенного сотрудника)r   r   r   )r   r}   r4   r   rA   rB   Zhrefr   r#   get_supervisorrU   )r&   Zlinkstaskr   r    r    r!   _check_does_not_work  s    

zCmfPerson._check_does_not_workc                    sh    fdd |  ddg d}| jrB| jjr6| jj}n | jj}|sdtj }|j  |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)headr4   r
   r   rT   rP   )Zorg_unit	recursionr    r!   r     s    
z+CmfPerson.get_supervisor.<locals>.recursionzprimary_role.supervisorzprimary_role.tree_parent.headNr   )	rT   r   
supervisorrP   r4   r`   Zadmin_groupZ
rg_membersr   )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   )r0   r}   rT   Zincompatible_combination_coder"   r   rL   ra   )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_roleB  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}   r4   ZCmfAuthPluginDatar   rA   ZdirtyrU   )r&   Z	auth_datar    r    r!   _check_auth_dataN  s
    zCmfPerson._check_auth_datac              	   O   s   t jj|dgd}tj|ds4tj|jks4tjjrt jj|dgd}	|	sn|r\t j	j|d}t j||||d}	t
  |	  W 5 Q R X t jjdd	|gd
d	dggdgd}
|
rt
  |
j|	 |
jdd W 5 Q R X ntddd dS )uD   
        Добавить клиента для ServiceDesk
        rQ   r3   zsdesk-agent:defaultr0   )r   r   r)   )r   r   r   r   rn   ro   rq   zsdesk-client:defaultrp   r?   Tr   u   Клиента может добавлять только пользователь с ролью Агент или Владелец проекта, или Администраторr   N)r4   r@   r   r5   rb   rm   rQ   r1   r
   r   rV   rW   rU   rr   rp   rB   ra   )r   Z
project_idr   r   r   r   r   r   rD   r   rs   r    r    r!   register_sdesk_clientX  s:    

zCmfPerson.register_sdesk_client)company_namephone_numberc          	      O   sX   |r:t jj|d}|r"tddd t j|||d}|  | ||||dd}|  |S )Nr]   u^   Попросите ваших коллег пригласить вас через ссылкуTr   )r   Zemail1Zphone1)r   rI   r   r   r   )r4   r   r   ra   rU   )	r   r   rI   r   r   r   Zkargsr   userr    r    r!   create_sdesk_user  s    zCmfPerson.create_sdesk_user)save_kwargsc                   s0   | drtddd t j|d|i| d S )Nr   u   Назначение или открепление должности пользователю необходимо производить в "Структуре" в карточке должностиTr   r   )r   ra   r   update)r&   r   r   r   r   r    r!   r     s    
zCmfPerson.updatec                 C   s&   t jjr"| js"tj| j| jd| _d S )Nr   )r5   r   Ztwo_factor_optr2   r4   r   r   r   rZ   r    r    r!   
_check_2fa  s    zCmfPerson._check_2fac                    s
  |    | jjr| jr|   | jr8| j| jkr8| j| _|   |   |   | 	  | 
  |   |   | jjr| jr| jjs| jjstddd |   |   |   |   tt| j||}|   | jr| jrttj | jrtj| d}|  |S )Nu   Для включения SMS уведомлений необходимо указать номер мобильного телефонаTr   )rn   ) r   r   r}   r   rI   r   rz   r   r   r   r   r   r   r   r   Znumberr   ra   r   _calc_servicedesk_allowr   r   r   r
   rU   r   r   r   r   r   r4   ZCmfTimeTracker)r&   r   r   r   Zperson_timetrackerr   r    r!   rU     s6    
zCmfPerson.savec                    s2   |  ddg |   t j|| ttj d S )NrQ   r   )rT   r   r   deleter   r
   r   r%   r   r    r!   r     s    zCmfPerson.deletec                 C   sP   |rLt  }||d | }tj d| d}tj	|sLt
| |S )Nutf8/)hashlibr   r   encode	hexdigestr&   _AVATAR_DIRECTORYospathexistsmakedirs)r   rI   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 )Nr   )r4   r
   r  rI   rf   r  r  isdirlistdirisfileremover   set_gravatarr*   )r&   r   r   r  filefilepathr    r    r!   remove_avatar  s    zCmfPerson.remove_avatar)r   )emailsc              
   O   s  ddl m} g }tjtjd s0td |S tj	rHtj
jsXtjdkrXtdtj
 | }tj }| D ]}|dkr|qlt|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jj}|d|
|d}|jtj d|tj dd}td| d|  |j!dksH|j"dkrh|# }td| d|  qldd|g}td|  tj$j|d}|std tj$|||gdd}n&td |j% d! |j&'| d|_(t)*  |+  W 5 Q R X |'|j,j td" ql|S )#u   
        Регистрируем новых пользователей по email
        :param emails:
        :return:
        r   )sessionz/custom/org_namezCregister_persons: WARNING: org_name is not set, can't invite peopleTrueu.   Операция не доступна для Ni:	 Zguid)rI   ZissZiatZexpZjtisubzregister_persons:frominvite_must_change_passwordr   Zinvite_by_email)r   actioninvite_tokenr  z/auth/signup   )r   cookiestimeout,    zSigned up successfullyuE   ERROR: Не удалось отправить приглашение z: r   r>   u"   Ищем пользователя r   u)   Создадим пользователяT)rI   r   r0   r   u(   Добавим пользователя u    в группуz!register_persons: person saved ok)-requestsr  r  r  r  configPROJECT_DIRr5   r   Zis_local_userr6   r1   ZIS_BOX_VERSIONZCmfPermissionErrorr4   r`   r   r   ZAPP_FQDNr"   intr   r   rf   Z
create_jwtZrsa_sign_pack_jwtZCmfGlobalSettingsr   r  r   ZAUTH_SERVER_URLrequestr  status_coder   Zjsonr
   r   r0   rB   r   rV   rW   rU   r*   )r  r   r   r  rC   srg   r   ZpayloadZjwtr  r  r   r   r   r   r    r    r!   register_persons  sl    


 


zCmfPerson.register_personsc                 O   s   d S rY   r    r   r   r   r    r    r!   	sdesk_get"  s    zCmfPerson.sdesk_getr  c                O   s   dg}| j |d|i|}|S )Navatar_filenamer   r+   )r   r   r   r   r   r    r    r!   
public_get'  s    zCmfPerson.public_get)r   r   c                O   s   d S rY   r    )r   r   r   r   r   r    r    r!   public_list/  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_idro   r   )r   r   r   r]   )
r   r4   ZCmfDealrA   r*   r   r   ZcontactsZprimary_contactrU   )r&   r   r   ZdealsZdealr    r    r!   
start_chat3  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   r>   r.   r?   Z	invisibleZoffline)Zjs_idr   r   )r.   Z
is_defined_valuer4   r   r   r*   r   r5   r6   choicesrf   )r&   r   r   r    r    r!   _online_statusF  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   r>   r   r   Zis_internalr  r0   r:   r   Fr   ro   ZAdminsZUsers)object_fields	object_idr   )r   r   field_options_list)r   Zrelation_field_namer0  r1  r   r   r   r    r!   r2  S  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;%r:   ZLIKEr>   r?   u.   Возвращаем пользователя %   Неправильный номер: )r5   r   phonenumbersparseZformat_numberZPhoneNumberFormatZE164r4   r
   r   r   )	r   r   r   r   Z	phone_objZformat_phoner   r   r   r    r    r!   get_by_phonef  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 )Nr*   r<   tree_parent_idr   r?   r   )r4   Z
CmfOrgUnitZslistr*   insertr7  )Zou_idsZou_ids_nextZouquery_our    r!   r:    s    z.CmfPerson.get_org_units_list.<locals>.query_ou)rT   r   r7  rf   rB   )r&   r7   r8   rC   Zou_ids_firstrt   Zou_listr    r9  r!   get_org_units_list  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   r3  r  u@   Возвращаем пользователя с номером )r6  r5   r   r4   r
   rU   r   r   )r   r   r   r   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   r)   N)varsr4   r   r   callbackr   Znumber_e164)r&   Z
channel_idr?  Zchannelr    r    r!   
phone_call  s    zCmfPerson.phone_callc                 O   s0   t j| jst | j t| j d| S )Nr   )r  r  r  r   r  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  r   z.jpegwb)r)  r   rD  r  unlinkrU   r   r
   r  r*   rf   r   r"   base64Zurlsafe_b64decoder   r   rI   r   r   openwrite)r&   image
image_typer  r   r   rD  Z
image_datarC  Z
image_pathZ
image_filer    r    r!   
set_avatar  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{   )r  u.   Ошибка запроса к gravatar {}: {}r  )rI   r5   r   r   r   r   rf   lowerrL   r   r   r  r   r#  r   r   r   r   formatr$  r   Zcontent)r&   r  defaultZurlr   r   r    r    r!   fetch_gravatar  s     

zCmfPerson.fetch_gravatar<   )r   Zsoft_time_limitc                 K   s<   t jj| d}|t j| | }|j|ddd d S )Nr)   ZjpegF)rK  r  )r4   r
   r   rT   r   rP  rL  )r   r8   r   rJ  r    r    r!   r    s    zCmfPerson.set_gravatarc                 O   s   d S rY   r    r'  r    r    r!   public_get_org_units_list  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rd}| 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   r0   )rT   r   r}   r0   r4   r`   r   setr   r   r5   r   Zservicedesk_allow_auth_guestsra   rB   r  )r&   r   Zsdesk_groupr   r    r    r!   r     s@    

z!CmfPerson._calc_servicedesk_allow)T)N)NNN)NN)NNN)N)N)F)N)N)NNN)NN)NN)NNT)F)H__name__
__module____qualname__r   r!  r   classmethodr   r'   r-   r9   rE   propertyrM   rX   r[   ri   rm   rl   rz   r   r   r   r   r   staticmethodZ
celery_appr   r   r   r   r   r   r   r   rA   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rU   r   r  r  r&  r(  r*  r+  r,  r/  r2  r6  r;  r<  r@  rD  rL  rP  r  rR  r   __classcell__r    r    r   r!   r
      s   




#W.
!	

+	%
	
B



r
   c                   C   s
   t j S rY   )r4   r
   r   r    r    r    r!   r   #  r   r   )rG  Zbinasciir   rA  shutilr   r   Zrandomr   r4  ZCryptor   r  Zrequests.apir   Zcmf.data_providers.baser   Zcmf.includerx   Zbs4r   Zmodules.person.fieldsr	   r
   ZAPPZHOOK_CRON_HOURLYrB   r    r    r    r!   <module>   s4           