U
    [c                     @   sx   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m	Z	 d dl
Zd dlmZ G dd	 d	ejjjjZdS )
    N)	timedelta)FileStorage)relativedelta)*)CmfTUUID)CmfActiveEntityc                       s  e Zd ZdZdd Zdd Z fddZ fdd	Z fd
dZdd Z	dd Z
dd Z fddZdd Zdd Zdd Zdd Z fddZdd Z fd d!Z fd"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zdjd-d.Zdkd/d0Zdld1d2Zd3d4d5d6d7d8d9d:d;d<d=d>d?Zd@dA ZdmdBdCZdDdE ZdndFdGZ  fdHdIZ! fdJdKZ"e#do fdLdM	Z$e#dpdNdOZ%e#dq fdPdQ	Z&e'e(j)dRdSdrdTdUZ*e'dsdVdWZ+dXdY Z,dZd[ Z-dt fd]d^	Z.d_d` Z/dudadbZ0 fdcddZ1 fdedfZ2dvdhdiZ3  Z4S )wCmfTaskFc              	   C   s   | j dkrd S t| jjtjs"d S |  \}}|s:|s:d S | jsd| jjrZt	| jj
 d || _d S | js||r|tjj | _|r| j|kr| j| j kr|| _| jjrt	| jj
 d| j d| jj
 d| d d S )NcloseduK    не может быть пустой при плановом списке u'    не может быть дальше ())cache_status_type
isinstanceparentvaluemodels
CmfProject_calc_list_plan_interval
alarm_date
is_changed	cmf_alertcaptioncmffieldsCmfDateTimenowplan_end_dateselflist_plan_start_date_maxlist_plan_end_date_min r!   !./modules/task/models/cmf_task.py_calc_alarm_date_list   s,    

$zCmfTask._calc_alarm_date_listc                 C   s<   | j s8| jr8| jjr8| jjjdkr8| jj  r8| jj | _ d S Nr   )responsibler   r   r   
class_nameloadr   r!   r!   r"   _calc_responsible.   s    
zCmfTask._calc_responsiblec                    s   | j sB| jjsB| jjsB| jjsB| jjsB| jjsB| jjsB| jjsBd S t	 
  | jjr| jr| jjjdkr| jj r| jr| j| _| jr|   | jr| jjs| j r| j| j k r| j  d S r$   )is_newr   r   statusdeadlineactivitylistsplan_start_dater   super_calc_alarm_dater   r   r&   Zauto_alarm_dater'   r#   r   set_nowr(   	__class__r!   r"   r1   6   sN    


zCmfTask._calc_alarm_datec                    s   | j jr| j rdS | js<| jjs<| jjs<| j js<| j js<dS | jjrl| jrlt| jdrl| jj  rl| jj | _ | jjrd}| jjD ]}|| jj	kr|j  }q|s| jr| jd j  }|r|| _ | j st
   | j r| j jdgd dS )u   
        Вычисляем вид дейтельности
        Метод вызывается из базового класса.
        :return:
        Nr-   r   r   r   )r-   r   r*   r   r.   is_nullhasattrr'   newoldr0   _calc_activityload_fields)r   Ztmp_activityobjr3   r!   r"   r:   Z   s:    


zCmfTask._calc_activityc                    s8   | j r| j j | _d S t   | js4tj|  d S N)parent_taskr   r'   r0   _calc_parentr   r   Z_calc_task_parentr(   r3   r!   r"   r?      s    
zCmfTask._calc_parentc                 C   s&   | j r
d S | jjsd S tj|  d S r=   )r*   r+   r   r   CmfTimeTrackerZtimetracker_task_change_statusr(   r!   r!   r"   _calc_timetracker   s
    zCmfTask._calc_timetrackerc                 C   s:   | j jsd S | j sd| _ | j | j | _| jdk r6d| _d S )Nr   )Ztime_estimater   
time_spentremaining_estimater(   r!   r!   r"   _calc_remaining_estimate   s    
z CmfTask._calc_remaining_estimatec                 C   s   | j s*| jjs*| jjs*| jjs*| jjs*d S |   d }| jrD| j}n8| jrbt| jjt	j
rb| j}n| jrp| j}n| jr|| j}|| _d S r=   )r*   Ztree_parentr   r   r>   	main_listZ_load_perm_fieldsr   r   r   ZCmfDocumentperm_parent)r   rF   r!   r!   r"   _calc_perm_parent   s,    	zCmfTask._calc_perm_parentc                    sT   t   }dd | jD |d< dd | jD |d< | j|d< | j|d< | j|d< |S )	Nc                 S   s   g | ]}| d ddgqS idnamecodeZto_json.0ir!   r!   r"   
<listcomp>   s     z1CmfTask.get_cache_fields_json.<locals>.<listcomp>r.   c                 S   s   g | ]}| d ddgqS rH   rL   rM   r!   r!   r"   rP      s     tags
is_checked	parent_idactivity_id)r0   get_cache_fields_jsonr.   rQ   rR   rS   rT   )r   retr3   r!   r"   rU      s    



zCmfTask.get_cache_fields_jsonc                 C   sp   d }d }| j D ]D}|jjr2|d ks,|j|kr2|j}|jjr|d ksL|j|k r|j}q|sh|rhtjj }||fS r=   )r.   r/   Zis_not_nullr   r   r   r   r   )r   r   r    Zw_listr!   r!   r"   r      s    
z CmfTask._calc_list_plan_intervalc                 C   sz  | j jr<t| j r|s<|s<| js&| jr,d | _d | _d | _d S d }| jrX| jrX| j| j }| j jrx|rx|| _|| _| j| _| jjr|r|| _| jjr|r|| _| jjr|s|r|d | _|r|r| jr| j|ks| j|k r| jjrt| jj d || _|r| j| | _n|r|| _|rP| jr8| j|krPt| jj d || _| jrv| jrv| j| jk rv| j| _d S )N   uP    установлена в соответствии с планом списка)	r.   r   lenr/   r   r   r6   r   r   )r   r   r    Zself_plan_shiftr!   r!   r"   _calc_plan_list   sZ    

zCmfTask._calc_plan_listc                 C   s   | j jr| j r| jdkr| jr| j | jk sT| jr<| j | jksT| js| j | j jdkr| j | j }| j | _| jr~| j j|7  _td |   d S )Nopen
   uM   План сдвинут в соответствии с будильником)	r   r   r   r/   r   daysr   r   
_calc_name)r   Z	date_diffr!   r!   r"   _calc_plan_nolist  s2    

		zCmfTask._calc_plan_nolistc                 C   sj   | j js*| js*| jjs*| jjs*| jjs*dS |  \}}t| j sH| j jrV| || n| 	  | 
  dS )u`   
        Ф-я вызывается из базового класса
        :return:
        N)r.   r   r*   r   r/   r   r   rX   rY   r^   r]   r   r!   r!   r"   
_calc_plan)  s"    zCmfTask._calc_planc                    s0   t    | jr | jj|  ntj|  dS )u?    Ф-я вызывается из базового класса N)r0   _calc_statusr   r   Z_calc_task_statusr   r   r(   r3   r!   r"   r`   A  s    
zCmfTask._calc_statusc                 C   s  | j jsL| jjsL| jjsL| jjsL| jjsL| jjsL| jjsL| jjsL| j	jsLdS | j
sd| jjrd| jrddS | jdkr| j| _| j| _d| _dS | jr| jjjdks| j p| j| _d| _| js| j| _| j| _d| _dS | jdg | j jsR| jrR| jjrR| jdkrR| jjr| jj| _| jjsN| jjrN| j rN| j| jjkrN| j | _dS | jj| _d| _d| _| j
r| j r| j | _| jr| j r| j | _n
| jj| _| j	dkr| jj| _d	| _dS )
G    Ф-я вызывается из базового класса
        NZ	in_reviewZapprove1_reviewr   Zapprove3_notassigned	cmf_ownerin_progressFZapprove2)r%   r   rb   r.   r   r+   waiting_forr6   r   approvedr*   r   approve_forapprove_for_placer   r&   r;   r9   r8   r(   r!   r!   r"   _calc_waiting_forK  sp    	
(

,



zCmfTask._calc_waiting_forc                    s:  t    | jjrd S | jj  | jjr>| jjjr>d | _d S | jjrR| jjrRd S | jjjr`d S | jjj	}t
j|d}t
j
t
jj}| jjr| jjs| jjr| jj	| | _d S | jjr| jr| jjdk r| jtjkr| jr| jj	| jj	kr| jj	| | _d S | jjr|| | _d S | jjr6| js6|| | _d S d S )N)r\   i  )r0   _calc_deadliner,   r   workflowZdefault_deadline_shiftr'   r6   r%   r   datetimer   r   timezoneutcZperiod_next_dater9   r8   r   cmf_created_atagerb   gcurrent_person)r   Z
days_shiftshiftr   r3   r!   r"   ri     sP    







zCmfTask._calc_deadlinec                    s    | d| jdk t jf |S )NZstrikethroughr	   )
setdefaultr   r0   _place_notify)r   kwargsr3   r!   r"   rt     s    zCmfTask._place_notifyc                 O   s$   t jj|ddgd}| j| | S NrI   z
members.idr5   )r   CmfListgetr.   remove)r   Zsrc_list_idargsru   Zsrc_listr!   r!   r"   remove_from_list  s    zCmfTask.remove_from_listc                 O   s$   t jj|ddgd}| j| | S rv   )r   rw   rx   r.   append)r   Zdst_list_idrz   ru   Zdst_listr!   r!   r"   copy_to_list  s    zCmfTask.copy_to_listc                 C   s   t j|j| d | S )N)r<   )r   CmfActiveEntityFilterrx   Zadd_active_entity)r   	filter_idr!   r!   r"   apply_filter  s    zCmfTask.apply_filterc                 C   s8   t jj|ddgd}|jr4| j|j | jdd | S )Nr   
filter_tagr5   T)Z	only_data)r   r~   rx   r   rQ   ry   save)r   r   Zactive_entity_filterr!   r!   r"   remove_from_filter  s
    zCmfTask.remove_from_filterNc                 O   s   |  dg |stddd |s,tddd t|}t|}|tjkrV| | n(|tjkrl| | ntd| dd |tjkr| 	| n(|tjkr| 
| ntd| dd | S )Nr.   u   Укажите from_idTabortu   Укажите to_idu(   Не могу перместить из u&   Не могу перместить в )r;   r   r   Zget_cls_by_tuuid_strr   rw   r{   r~   r   r}   r   )r   Zfrom_idZto_idrz   ru   Zfrom_clsZto_clsr!   r!   r"   move  s$    





zCmfTask.movec                 K   s   |d }|sdS |d dkr dS | d}tjjddd|gddd	| d
gggdgd}|sl| jjshdS dS |s|| j| dS )Ntoken_sanitizedFr   u   #№ORrJ   ILIKEaliasz%"z"%)filterr   T)lstripr   ZCmfTagrx   rJ   r   rQ   r|   )r   	only_namectxr   tagr!   r!   r"   _process_tag_token&  s*    
	zCmfTask._process_tag_tokenc                 K   s   |d }|sdS | dsdS |d}t|dk r8dS dddgdd	d
d| dgdd
d| dggg}tjj|d}|s| jjrdS dS |s|| _dS )Nr   F@   
user_local==Tr   rJ   r   %Zloginr   )	
startswithr   rX   r   	CmfPersonrx   rJ   r   r%   )r   r   r   r   Z_filterpersonr!   r!   r"   _process_responsible_tokenK  s*    

z"CmfTask._process_responsible_tokenu   Январьu   Февральu   Мартu   Апрельu   Майu   Июньu   Июльu   Августu   Сентябрьu   Октябрьu   Ноябрьu   Декабрь)            r            	   r[         c                 C   s(   |  }|  }|d| d| fkS )N#   №)lower)r   stringZhashtagr!   r!   r"   hashtag_cmpw  s    zCmfTask.hashtag_cmpc           	      K   s   |d }| j  D ],\}}| }|d| d| fkr qDqdS |s| jsb|| jj krbdS tjjtjj	dj
dddddd	}||j }|dk r|d
7 }|t|
 d7 }|tddd }| jr|j| jjjkr| jjj|jkrdS || _|| _dS )Nr   r   r   FT)Ztzr   r   )ZdayZhourZminutesecondZmicrosecondr   )months)r   r\   )_monthsitemsr   r*   rJ   r9   rk   r   rl   rm   replacemonthr   r/   r   Zyearr   )	r   r   r   r   Z	month_idxr   r/   rr   r   r!   r!   r"   _process_month_token}  s>    
zCmfTask._process_month_tokenc                 C   s   | j dd dS )ra   T)r   N)_calc_from_namer(   r!   r!   r"   r]     s    zCmfTask._calc_namec                 C   sj  | j js$| jjs$| jjs$| jjs$d S | j jp.d}| }g }|sFg | _t|D ]`\}}| 	d}t
  }|d= | jf |rqN| jf |rqN| jf |rqN|| |sNqNqNg }d}	|r|| t|d }
||
 d||
< t| jdd d	D ]}d
}	|d|j   q| jr>d
}	| j| jjj }|d|  |	rZ|rZ||
  d7  < d|| _ d S )N z.,;:?!r   Fr   .c                 S   s   | j jS r=   )rJ   r   )r   r!   r!   r"   <lambda>      z)CmfTask._calc_from_name.<locals>.<lambda>)keyTr   r
   )rJ   r   r/   rQ   r%   r   split	enumerater   striplocalscopyr   r   r   r|   extendrX   rstripsortedr   r   join)r   r   rJ   Zname_tokensZundefined_tokensidxtokenr   r   Zneed_dotZdot_token_posr   r   r!   r!   r"   r     sV    


zCmfTask._calc_from_namec                    sB   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}t   | S )Nzparent.project_typezparent.auto_alarm_datezparent.logic_prefixzparent.activity.prefixr>   ztags.tag_categoryzlists.plan_start_datezlists.plan_end_datezlists.ordernozlists.perm_has_aclzlists.sys_typezlists.logic_prefixzmain_list.plan_start_datezmain_list.plan_end_datezmain_list.ordernozmain_list.perm_has_aclzactivity.prefixzworkflow.default_deadline_shiftzcomments.log_levelrg   rf   cmf_modified_byrE   Ztimetracker_history)r0   save_preload_fields)r   r   r3   r!   r"   r     s4    zCmfTask.save_preload_fieldsc           	         s  | j jr|   |   |   |   | jj }rHt|drH|	|  | j
jr| jrt| j
jt| j
j D ]}|| jkrnd | _qn| jjr| jjr| jjs| jj| j
kr| j
| jj | j
D ]"}|jdks|jdkr|| _ qq| j
jr:| js:t| j
jt| j
j D ]*}|jdks*|jdkr|| _ q:q| jjr| jjr| jjr| jj| j
kr| jj| j
kr| j
| jj | jjr| jr| j| j
kr| j
| j | j
jr
t| j
jt| j
j D ]0}|jdkrtd|j  d| j  ddd	 qt j||}| j
jr.ttjj d
D ]&}t| |jr2ttjj  qZq2| jjr| jrt| jjtjr| j| j | jjr| jdkr|  t!j"j# | j$dd |S )Nhook_task_savelist.agile_epicz	list.baser	   uM   Нельзя добавить задачу в Закрытый список "z" - ""Tr   )r+   r   rQ   r%   r/   re   r   )priority)%rJ   r   r   rA   rD   r?   r   r   r7   r   r.   rE   setr9   r8   ry   logic_prefixr|   r   r   r0   r   Zcmf_deferred_taskr   rw   Zrecalculate_cachegetattrr~   rQ   r   r   Zhook_task_tags_changedZ_clear_notifyrp   rq   rI   Z_update_opened_notifies)	r   rz   ru   r   Zremoved_listlZappended_listZself_instance
field_namer3   r!   r"   r     s\    



 
"

$zCmfTask.savec                    s   |sg }|sdg}|sg }|dddgddddgddd ggg}|oH| d	}|r\|d	d
|gg}|d |d t j|f||||d|S )NrJ   r   z!=r	   r   Zsys_typeZtrashr   rS   =r   object_fieldsr   r   order_by)rx   r|   r0   field_options_list)clsrelation_field_namer   r   r   r   ru   rS   r3   r!   r"   lists_options_listS  s2    

   zCmfTask.lists_options_listc                 K   sF   |sg }|r*| dd dkr*|dddgg}| j|f||||d|S )NZparent_logic_prefixzproject.agiler   r   r   r   )rx   r   r   r   r   r   r   r   ru   r!   r!   r"   main_list_options_listj  s
    zCmfTask.main_list_options_listc                    sf   |dkr$| j |f||||d|S |dkrH| j|f||||d|S t j|f||||d|S )Nr.   r   rE   )r   r   r0   r   r   r3   r!   r"   r   {  s       zCmfTask.field_options_listT)Zsystem_taskc              	   K   sd  t d|  d|  |  d| }t|d }	d|	 }
tjj|
ddgd}|r|jd	krt d
 |j	
 |_|j  tj|dd  nd}|rtjj|dgd}d}|rtj|}d}|rtjj|}n|r|jr|j}t d|j d|j d|  tj|
| | d|pd ||||d}|j  |  t d|j d|j d |jjS )u  
        Метод для автоматического создания задач.
        Переоткрывает задачу, если такая уже есть закрытая.
        Уникальность задачи определяется по topic + text.
        Дополнительную, переменную информацию, например параметры запроса, можно передать в extra_text
        z
Auto task z, info: /zutf-8zAuto-r   r+   )rK   r   r	   zAuto task reopenu'   Переоткрываем задачу)r   textNdefault_projectr5   zNew auto task for r   z
) project 
r   )rK   rJ   r   r%   rb   r   r   r   )printhashlibZmd5encodeZ	hexdigestr   r   rx   r   rj   Zget_default_statusr+   r   r2   Z
CmfCommentr   r   r   r   r   Zget_obj_by_tuuid_strr   rJ   rK   rI   r   )rJ   r   Z
extra_textr   responsible_idZcmf_owner_idrS   _kwargsZtask_keyZ	task_hashZ	task_codetaskr%   rb   r   r!   r!   r"   	auto_task  sH    



  
zCmfTask.auto_taskc                 O   s   t jjdddgd}dddg}dddg}|r:dd|jgg t }|D ]P}t jjdd|jgdddggd}	t jjdd|jgd}
||jj	|	|
d qD|S )	Nr   r   Tr   r   rc   r   )rc   count)
r   r   listrI   dictr   Zslistr   rs   r   )r   r   rz   ru   personsZin_progress_filterZcount_filterr   resultZin_progress_countr   r!   r!   r"   get_responsibles_tasks_count  s    

z$CmfTask.get_responsibles_tasks_countc                O   sb   |  ddddg | jjr^| jjdkr^|| jjkr6dS || jjkrFdS |dd | jD kr^dS d	S )
Nr   rd   r%   	executorsrc   Tc                 S   s   g | ]}|j jqS r!   )rI   r   )rN   r<   r!   r!   r"   rP     s     z%CmfTask.notify_os.<locals>.<listcomp>F)r;   r   r9   rd   rI   r%   r   )r   	person_idrz   ru   r!   r!   r"   	notify_os  s    zCmfTask.notify_osc                 C   s`   | j js<| jjs<| jjs<| jjs<| jjs<| jjs<| jjs<d S | jjrN| jrNd S | j	
| | _d S r=   )r-   r   r   r   rj   r6   r.   Z
logic_typerE   Z	scheme_wfZcalc_workflowr(   r!   r!   r"   _calc_workflow  s$    	zCmfTask._calc_workflow   Изменена задачаc              
      s   | j r
d}|r| dddddddd	g |dkrV| jjd
k rV| j| jjj||d d S | jdkr| j	g}| j
r| j
jdkr|| jj	 |D ]}| j|jj||d qd S t jf |||d| d S )Nu   Создана задачаr   zparent.cmf_owner_assistantzparent.cmf_ownerrn   rd   r   rb   r   <   )r   rJ   msgrc   r   )r   notify_namer   )r*   r;   rn   ro   rt   rd   rI   r   r   rb   rS   	type_namer|   r   r0   all_place_notify)r   r   r   r   ru   r   r   r3   r!   r"   r     sD        
zCmfTask.all_place_notifyc                 C   s,   | j f || jdd}| j|d |jjS )u    Создание задачи из шаблона
        :param self: Шаблон документа
        :param params: Параметры для шаблона
        :return: Идентификатор новой задачи
        F)for_template)r   )Zcreate_from_templateget_additional_clone_attrsZcopy_attachmentsrI   r   )r   paramsZnew_taskr!   r!   r"   create_task_from_template  s    z!CmfTask.create_task_from_templatec                 C   sV   ddd}| j ddgd | jr@| jr@tj | j| j  |d< |sRtj |d< |S )uu   Дополнительные настройки создания шаблонов из задач и наоборотN)r   r,   r/   r,   r5   r   )r;   r/   r,   rk   r   )r   r   Zattrsr!   r!   r"   r     s    
z"CmfTask.get_additional_clone_attrsc                    s&   | j dgd | jdkrdS t  S )uB    Шаблон уведомлений для разных workflow r   r5   ztask.ticketzhelpdesk_mail_notification.html)r;   r   r0   +get_default_mail_notification_template_namer(   r3   r!   r"   r     s    
z3CmfTask.get_default_mail_notification_template_namec                    s    |dkrdS t  j|f||S )N)r   r/   r   re   r   )r0   _get_field_log_level)r   r   rz   ru   r3   r!   r"   r   !  s    zCmfTask._get_field_log_level   Добавленоc                 C   s   t j| |||S r=   )r   r@   Ztimetracker_task_change_time)r   rB   rC   r   r!   r!   r"   timetracker_change_time'  s    zCmfTask.timetracker_change_time)NN)F)F)F)F)NNNN)NNNN)NNNN)NNNNNN)N)Nr   )T)r   )5__name__
__module____qualname__Zmenu_tree_show_objr#   r)   r1   r:   r?   rA   rD   rG   rU   r   rY   r^   r_   r`   rh   ri   rt   r{   r}   r   r   r   r   r   r   r   r   r]   r   r   r   classmethodr   r   r   staticmethodZ
celery_appr   r   r   r   r   r   r   r   r   r   r   __classcell__r!   r!   r3   r"   r      s   $&	
	A
a<  
!
%

*
9Q                     	
          -#

r   )rk   r   r   Zwerkzeug.datastructuresr   Zdateutil.relativedeltar   Zcmf.includeZcmf.fields.base_fieldsr   Zmodules.task.fields.cmf_taskmodulesZcommon.models.cmf_active_entityr   r   r   Zcmf_taskr   r!   r!   r!   r"   <module>   s   