U
    >hp                     @   sr   d dl m Z mZmZmZ d dlmZ d dlZd dlT d dlm	Z	 d dl
mZ e ddd	ZG d
d dejjZdS )    )datetimetime	timedeltatimezone)PathN)*)commit_all_ds)
is_weekendtc                 C   s$   | j ddd| jdt| jd d S )Nr   )secondZmicrosecondminutehour   Zhours)replacer   r   r   r
    r   0./modules/staff_control/models/cmf_person_var.py
round_hour   s    r   c                       s  e Zd ZdZejjjdddddg Zedd Z	ed	d
 Z
edbddZeeddddZedd Zdd Zdd Zeedddddd Zdd Zedd Zedd d!d"Zd#d$ Zeeddddd%d& Zeeddddd'd( Zed)d* Zed+d, Zed-d. Zd/d0 Zdcd1d2Zddd3d4Z ded5d6Z!dfd7d8Z"ed9d: Z#ed;d< Z$ed=d> Z%ed?d@ Z&dAdB Z'dgdDdEZ(edFdG Z)dHdI Z*dJdK Z+dLdM Z,dNdO Z-dPdQ Z.dRdS Z/dTdU Z0dVdW Z1dXdY Z2dZd[ Z3d\d] Z4 fd^d_Z5 fd`daZ6  Z7S )hCmfPersonVarTupdate_recent_options_listupdate_recents_objget_or_createpingpublic_update_recents_objc                 O   s   | j ||S Nr   clsargskwargsr   r   r   public_ping   s    zCmfPersonVar.public_pingc                 O   s   | j ||S r   r   r   r   r   r   
sdesk_ping!   s    zCmfPersonVar.sdesk_pingNc                 C   sN   |sg }| ddddg tjs(td| jtjj|d}|sJ| tjd}|S )Nperson.on_vacationbrowser_timezonelast_ping_atZcmf_modified_byz'get_or_create g.current_person == False)	person_idfields)person)extendgcurrent_person
ValueErrorgetid)r   r'   cr   r   r   r   %   s    zCmfPersonVar.get_or_create)phonetextreturnc                 C   sd   |  dg |  }|s td|js2| d n.| jjsBtjj	sN| d nt
j||d  dS )u>  
        Враппер для отправки СМС с проверкой настроек контроля сотрудников.
        TODO: расширить настройки отправки СМС под каждый случай и проверять их в вызывающей функции
        person.no_staff_controlu   Баг: нет настроек контроля сотрудников в БД, должны были создаться выше.uj   В настройках контроля сотрудников выключена отправка СМСuP   В настройках отключен контроль сотрудников)r0   r1   N)load_fieldsget_settingsAssertionErrorsend_smslogr(   no_staff_controlr*   Zglobal_settingsZstaff_control_enabledmodelsZCmfSMSsend)selfr0   r1   settingsr   r   r   r7   5   s    zCmfPersonVar.send_smsc                 O   s   t j|d}tdtjjj| |dp2t	 }| j
t	t|ddg d}|jjsb|jdkrhd|_z(t|j| }|j|kr||_W n$   td	|j  d
|_Y nX |jjdkr|j  |jjs|jjs|jjr|j|d ntd |S )Nnowzping updater'   online_statusr%   )r'   offlineZonlineuK   Не удалось обработать таймзону браузера r   i  zping update skip 7*60)dateutilparserparser-   printr*   r+   Zloginvaluelistr   setr?   is_nullinttzinfoZ	utcoffsettotal_secondsr$   debugr%   Zageset_now
is_changedsave)r   r   r    Zbrowser_nowr'   r/   Zbrowser_now_timezoner   r   r   r   F   s&    


zCmfPersonVar.pingc                 C   sx   t  r| d dS | dg | js4| d dS | jjrJ| d dS | jjr`| d dS | jst| d dS dS )	N   Сегодня выходнойFperson.*u   Не выставлен person"   Больше не работает   В отпускеu(   Не выставлен browser_timezoneT)r	   r8   r4   r(   does_not_workon_vacationr$   r<   r   r   r   _should_processb   s"    




zCmfPersonVar._should_processc                 C   s\   |sdS t  r| d dS |jr0| d dS |jrD| d dS |jrX| d dS dS )NFrP   uC   Отключен контроль работы сотрудникаrR   rS   T)r	   r8   r9   rT   rU   )r<   r(   r   r   r   _should_process_by_person{   s    



z&CmfPersonVar._should_process_by_personz@hourly)Z	only_onceZ
system_jobZschedulec               	   C   s   t d d} tjjddddddd	d
gddd g| | d gd}| d7 } |sJq|D ]6}z|  W qN tk
r   td|  Y qNX qNt  qd S )Nu4   Проверка открытых браузеровr   r$   r%   person.phone_mobileperson.phoner3   person.does_not_workr#   r?   !=  )r'   filterslice    Ошибка обработки )	rD   r:   r   rF   check_browser_open	Exceptionlogging	exceptionr   )iZpersonsr/   r   r   r   all_check_browser_open   s0          
z#CmfPersonVar.all_check_browser_openc                 O   sZ   d| j g}| jr6| jdg || jjj| jjjg7 }dd | D }t|||  d S )Nu'   Контроль сотрудниковphone_mobilec                 S   s   g | ]\}}| d | qS )=r   ).0kvr   r   r   
<listcomp>   s     z$CmfPersonVar.log.<locals>.<listcomp>)	coder(   r4   namerE   rg   numberitemsrD   )r<   r   r    prefixZ
kwargs_fmtr   r   r   r8      s    
zCmfPersonVar.logc                 C   sD   t | }t|dr|jS td}d}| r8|  }||_|jS )NZ
__org_namezcustom/org_name )typehasattrZ_CmfPersonVar__org_namer   exists	read_textstrip)r<   r   Zorg_name_pathorg_namer   r   r   rx      s    
zCmfPersonVar.org_namezmodels.CmfStaffControlSettings)r2   c                 C   s   t ddstj t_tjS )Nr*   staff_control_settings)rt   r:   ZCmfStaffControlSettingsr   r*   ry   rV   r   r   r   r5      s    
zCmfPersonVar.get_settingsc                 C   s  |   sd S | j }|  }t||jj| j}t||j	j| j}|t
dd8 }|| j  k oh|k n  }|s| d| d| j d|  d S | jr| jj| j}| j|  }|dk }nd }d }d}| jd| j| jj|||d |r| d	 d S | jjs| jd
kr d
| _|   | jjj}	|	s>| d d S | jjdkrf| d| jj d d S d}
| jr|
dtj d7 }
| d | |	|
 | j  |   d S )N   r   u    не рабочее время: z < i  Fra   )r>   r%   ping_tzseconds_since_last_pingis_ping_recentub   Пользователь недавно присылал данные в рабочее времяr@   uD   У пользователя не установлен телефон)
      u   Не нашли на рабочем месте, но не уведомляем, т.к. не 10 или 14 часов (сейчас )u   ЦРМ не может найти Вас на рабочем месте. Проверьте, что запущен браузер. (ue   Уведомляю пользователя о том что нужно открыть браузер)rW   r>   dater5   r   ZcombineZwork_start_atrE   py_browser_timezoneZwork_end_atr   r8   r%   
astimezonerK   r?   rH   rO   r(   rg   ro   closest_hourr   rx   ZconfigZAPP_FQDNr7   Zlast_sms_atrM   )r<   Ztoday_tzr=   Z
work_startZwork_endZis_working_timer{   r|   r}   rg   r1   r   r   r   ra      sr    
    
	




zCmfPersonVar.check_browser_openc                  C   s   t d t rt d d S d} tjjdddddd	d
dddddddg| | d gd}| d7 } |s`q|D ]6}z|  W qd tk
r   td|  Y qdX qdt	  qd S )Nu:   Проверка задач с крайним срокомu   Выходнойr   r$   zperson.emailrZ   rY   z+person.primary_role.supervisor.phone_mobilez6person.primary_role.supervisor.person.no_staff_controlz3person.primary_role.supervisor.person.does_not_workz1person.primary_role.supervisor.person.on_vacationr3   r[   vacation_startvacation_endr#   rQ   r]   )r'   r_   r`   )
rD   r	   r:   r   rF   check_tasks_deadline_wraprb   rc   rd   Z
cmf_commit)re   Zperson_var_listZscr   r   r   all_check_tasks_deadline  s@          	
z%CmfPersonVar.all_check_tasks_deadlinec               
   C   s   t d tjjdddgdddgdd	t  gd
dt  ggdD ]} |   |   qFt d tjjdddgdddgdddt  gddd gd
dt  gd
dd gggdD ]$} t | j	 d |   |   qd S )Nu:   Выставляем ушедших отпускниковZ
user_local==TrU   rh   Fr   z<=r   z>=r^   u>   Выставляем пришедших отпускниковOR><z Not on vacation)
rD   r:   Z	CmfPersonrF   r   Zutcnowr   Z_calc_vacationrO   rn   )pr   r   r   all_check_person1  s0    


zCmfPersonVar.all_check_personc                 C   s&   | j rtt| j jdS t  jS )N)Zseconds)r$   r   r   rE   r   r>   r   rJ   rV   r   r   r   r   M  s    z CmfPersonVar.py_browser_timezonec                 C   s   t jtjd| jS )N)Ztz)r   r>   r   Zutcr   r   rV   r   r   r   r>   U  s    zCmfPersonVar.nowc                 C   s
   t | jS r   )r   r>   rV   r   r   r   r   Z  s    zCmfPersonVar.closest_hourc                 O   s   | j   |  sd S | j}|jdd}|jdd}|jdd}||krl| d | j|d | j|d nn||kr| d | j|d | j	|d nB||kr| d | j
|d | j|d n| d	| d
|  d S )Nr   )r         u-   12 часов для пользователяr>   u-   13 часов для пользователяu-   16 часов для пользователяuF   Не время для уведомлений по дедлайнам  )r(   Zcalc_staff_control_blockedrW   r   r   r8   )notify_responsible_overdue_deadline_tasks&notify_responsible_open_deadline_tasks#notify_owner_overdue_deadline_tasks notify_owner_open_deadline_tasks(notify_supervisor_overdue_deadline_tasks%notify_supervisor_open_deadline_tasks)r<   r   r    r   Zhour_notify_responsibleZhour_notify_ownerZhour_notify_supervisorr   r   r   r   ^  s(    



z&CmfPersonVar.check_tasks_deadline_wrapc                 C   s   |s
| j }tjjdd| jjgdd|gdddggdd	d
dddddddddgd}|r| jj}|jsr|j  ||_	n|j	
  |j	j|kr||_	|jr|jdd n(| jjr| jj}d |_g |_	|jdd |S )Nwaiting_for_idr   deadliner   cache_status_typer\   CLOSEDcmf_owner.phonezcmf_owner.phone_mobilezcmf_owner.no_staff_controlzcmf_owner.does_not_workzcmf_owner.on_vacationrn   
alarm_datestatusactivity_id	parent_idlistsr^   r'   T)Z	only_data)r>   r:   CmfTaskrF   r(   r.   rE   Zstaff_control_blocked_daterM   Zstaff_control_blocked_tasksloadrN   rO   )r<   r>   resr(   r   r   r   get_overdue_deadline_tasks  sJ            

z'CmfPersonVar.get_overdue_deadline_tasksc              
   C   sf   |s
| j }tjjdd| jjgddd|tdd gdd|tdd ggd	dd
ggddddddddgdS )Nr   r   r   Zstatus_modified_atr      ZdaysZcmf_modified_atr   Z	IN_REVIEWzresponsible.phonezresponsible.namer   r   r   r   r   r   r   r>   r:   r   rF   r(   r.   r   r<   r>   r   r   r   get_overdue_in_review_tasks  s(    
      z(CmfPersonVar.get_overdue_in_review_tasksc                 C   st   |s
| j }tjjdd| jjgddd gdddgdd|td	d
 gddd gddd|gdd|gggddddddddgdS )Nr   r   r   r\   r   ZOPENcmf_created_atr   r   )Zminutesresponsible_idr   r   r   rn   r   r   r   r   r   r   r   r   r   r   get_open_deadline_tasks  s.          z$CmfPersonVar.get_open_deadline_tasksc              
   C   s   |s
| j }tjjddd| jjgdd| jjgggd}tjjdddd	 |D gd
ddgdddd gddd ggdd|tdd gdddggddddddddgd}|S )Nr   Zcmf_owner_idr   Zcmf_owner_assistantsINr   r   c                 S   s   g | ]
}|j qS r   )r.   )ri   Zprojectr   r   r   rl     s     z7CmfPersonVar.get_not_approved_tasks.<locals>.<listcomp>ZapprovedFr   r   r   r   r   r   r   r\   r   r   rn   r   r   r   r   r   )r>   r:   Z
CmfProjectrF   r(   r.   r   r   )r<   r>   Zprojectstasksr   r   r   get_not_approved_tasks  s.          z#CmfPersonVar.get_not_approved_tasksc                 C   s   |   sg S |  S r   )rW   r   rV   r   r   r   _overdue_deadline_tasks  s    z$CmfPersonVar._overdue_deadline_tasksc                 C   s$   |   sg S | jjdk rg S |  S N   )rW   r>   r   r   rV   r   r   r   _overdue_in_review_tasks  s
    z%CmfPersonVar._overdue_in_review_tasksc                 C   s$   |   sg S | jjdk rg S |  S r   )rW   r>   r   r   rV   r   r   r   _open_deadline_tasks  s
    z!CmfPersonVar._open_deadline_tasksc                 C   s$   |   sg S | jjdk rg S |  S r   )rW   r>   r   r   rV   r   r   r   _not_approved_tasks  s
    z CmfPersonVar._not_approved_tasksc                 C   s<   | j jj}|s| d d S |jj}|s6| d d S |j S )Nu-   Не указана основная рольuK   Не указан непосредственный руководитель)r(   Zprimary_rolerE   r8   
supervisor)r<   ZprZsupervisor_roler   r   r   get_supervisor  s    


zCmfPersonVar.get_supervisor   Дедлайнc                 C   sP   | d| j jj dt| d}dt| d }||d jjd | d 7 }|S )Nu    у r   z)

      r   z...)r(   rn   rE   len)r<   r   rq   sms_textmlr   r   r   get_smart_sms_text   s     zCmfPersonVar.get_smart_sms_textc                 C   s:   i }| D ],}|j jj}||kr&g ||< || | q|S r   )	cmf_ownerr.   rE   append)r   r   taskrj   r   r   r   tasks_group_by_cmf_owner(  s    
z%CmfPersonVar.tasks_group_by_cmf_ownerc                 C   sd   | j |d}|s| d d S dt| d}| jrD|d| j 7 }| d | | jjj| d S )Nr   A   Нет открытых задач с крайним срокомu2   У вас есть открытые задачи (uH    шт). Нужно взять в работу или перенести.    Подробности в u@   Уведомляю о своих открытых задачах)r   r8   r   rx   r7   r(   rg   ro   r<   r>   r   r   r   r   r   r   4  s    

z3CmfPersonVar.notify_responsible_open_deadline_tasksc                 C   s   | j |d}|s| d d S | |}| D ]J}|d j}|j  | j|dd}| d|j d | 	|jj
| q0d S )Nr   r   r   ,   Задачи не взяты в работуrq       Уведомляю овнера u<    об открытых задачах исполнителя)r   r8   r   valuesr   rg   r   r   rn   r7   ro   r<   r>   r   Ztasks_by_ownerownerr   r   r   r   r   F  s    



z-CmfPersonVar.notify_owner_open_deadline_tasksc                 C   sx   | j |d}|s| d d S |  }|s8| d d S |j  | j|dd}| d|j d | |jj| d S )Nr   r   B   Нет непосредственного руководителяr   r   ,   Уведомляю руководителя u>    об открытых задачах подчиненного)	r   r8   r   rg   r   r   rn   r7   ro   )r<   r>   r   r   r   r   r   r   r   Y  s    


z2CmfPersonVar.notify_supervisor_open_deadline_tasksc                 C   sd   | j |d}|s| d d S dt| d}| jrD|d| j 7 }| d | | jjj| d S )Nr   I   Нет просроченных задач с крайним срокомu:   У вас есть просроченные задачи (u:    шт). Нужно решить или перенести.r   uH   Уведомляю о своих просроченных задачах)r   r8   r   rx   r7   r(   rg   ro   r   r   r   r   r   o  s    

z6CmfPersonVar.notify_responsible_overdue_deadline_tasksc                 C   s   | j |d}|s| d d S | |}| D ]V}|d j}| |sN d S |j  | |}| d|j	 d | 
|jj| q0d S )Nr   r   r   r   uB    о просроченных задачах исполнителя)r   r8   r   r   r   rX   rg   r   r   rn   r7   ro   r   r   r   r   r     s    





z0CmfPersonVar.notify_owner_overdue_deadline_tasksc                 C   s   | j |d}|s| d d S |  }|s8| d d S | |sFd S d}|D ]"}|j}|d| d|j d7 }qN|j  | |}t	j
j|||dd	 | d
|j d | |jj| d S )Nr   r   r   rr   z
<p>
<a target="_blank" href="z">z
</a>
</p>
   )r(   rn   msgpriorityr   uD    о просроченных задачах подчиненного)r   r8   r   rX   hrefrn   rg   r   r   r:   Z	CmfNotifyZplace_notifyr7   ro   )r<   r>   r   r   r   r   r   r   r   r   r   r     s<    




z5CmfPersonVar.notify_supervisor_overdue_deadline_tasksc                 C   s   | j jr,| dg td| j | jgd | jjrX| dg td| j | jgd | jjrtd| j | jj| jj| jj d| jgd d S )Nr&   zevent-person-var-favorites-)Zevent_personsz,event-person-var-show_in_main_menu_projects-zevent-person-var-online_status-)r.   rn   )	Z	favoritesrN   r4   Zcmf_emit_eventr&   Zshow_in_main_menu_projectsr?   rE   choicesrV   r   r   r   emit  s    zCmfPersonVar.emitc                 O   s   |  | j | d S r   )_set_recentZrecents_objr   r<   recentsr   r    r   r   r   r     s    zCmfPersonVar.update_recents_objc                 O   s   d S r   r   r   r   r   r   r     s    z&CmfPersonVar.public_update_recents_objc                 O   s   |  | j | d S r   )r   Zrecents_opt_listr   r   r   r   r   r     s    z'CmfPersonVar.update_recent_options_listc              
      s  |s||_ |   d S t  g  fdd}zt|s@t|rtdkrNqt|rt|r|d d |d d kr|| q||j  q0t|r|| q0t|r0||j  q0W n@ tk
r } z"td| d| d|  g W 5 d }~X Y nX |_ |   d S )Nc                    s2   |  d}|d  kr. |d  | d S )Nr   Z	object_id)popaddr   )rF   objZobjs_idsr   r   r   
_push_from  s    
z,CmfPersonVar._set_recent.<locals>._push_fromd   r   r   zupdate_recent: 
)rE   rO   rG   r   KeyErrorZ	cmf_alert)r<   Zfieldr   r   er   r   r   r     s0    

zCmfPersonVar._set_recentc                    s   t   ddg S )Nr(   r   )supersave_preload_fieldsrV   	__class__r   r   r     s    z CmfPersonVar.save_preload_fieldsc                    s   | j jr| j | _t jf |S r   )r(   rN   r   r   rO   )r<   r    r   r   r   rO     s    zCmfPersonVar.save)N)N)N)N)N)r   )8__name__
__module____qualname__ZTEXKOM_no_cachecmfr:   	CmfEntityZapi_methodsclassmethodr!   r"   r   strr7   r   rW   rX   staticmethodZcmf_deferred_jobrf   r8   propertyrx   r5   ra   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   r   rO   __classcell__r   r   r   r   r      s   



L


'
(




	
	
	

(!r   )r   r   r   r   pathlibr   rA   Zcmf.includeZcmf.data_providers.baser   Zcommon.weekendsr	   r   r   r:   r   r   r   r   r   r   <module>   s   