U
    hc                     @   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                       sb  e 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
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dd.d/Zdd1d2Zdd3d4Zd5d6d7d8d9d:d;d<d=d>d?d@dAZdBdC ZddDdEZdFdG ZddHdIZ dJdK Z! fdLdMZ" fdNdOZ#e$d fdPdQ	Z%e$ddRdSZ&e$d fdTdU	Z'e$d fdVdW	Z(e)e*j+dXdYddZd[Z,e)dd\d]Z-d^d_ Z.d`da Z/dbdc Z0ddde Z1ddgdhZ2ddidjZ3dkdl Z4d fdndo	Z5dpdq Z6ddrdsZ7 fdtduZ8 fdvdwZ9ddydzZ:e)e*j+dXd{dXd|d}d~ Z;  Z<S )CmfTaskc              	   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   5   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:   Y   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 js&| jjs&| jjr"| jdks&d S | jsB| jdkrBtddd | jdkrtjj| jddgd| _	| j	rr| j	j
rz| j| _	d| _n6| jd	kr| jr| j| _	n| j| _	d
| _nd | _	d | _d S )N	task.epictask.subprojectuK   task.epic и task.subproject не могут быть без ПроектаTabortrA   epictree_hidden)r   sys_typer   rB   
subproject)
logic_typer   r   r>   logic_prefixr   r   Z	CmfFoldergettree_parentrF   rG   rH   r(   r!   r!   r"   _calc_tree_parent   s.    


zCmfTask._calc_tree_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*   rL   r   r   r>   	main_listZ_load_perm_fieldsr   r   r   ZCmfDocumentperm_parent)r   rT   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 rV   rZ   r[   r!   r!   r"   r^      s     tags
is_checked	parent_idactivity_id)r0   get_cache_fields_jsonr.   r_   r`   ra   rb   )r   retr3   r!   r"   rc      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/   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_nolist4  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   rg   rh   rm   rl   r   r!   r!   r"   
_calc_planJ  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"   ro   b  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   rq   r.   r   r+   waiting_forr6   r   approvedr*   r   approve_forapprove_for_placer   r&   r;   r9   r8   r(   r!   r!   r"   _calc_waiting_forl  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)rk   i  )r0   _calc_deadliner,   r   workflowZdefault_deadline_shiftr'   r6   r%   r   datetimer   r   timezoneutcZperiod_next_dater9   r8   r   cmf_created_atagerq   gcurrent_person)r   Z
days_shiftshiftr   r3   r!   r"   rx     sP    







zCmfTask._calc_deadlinec                    s    | d| jdk t jf |S )NZstrikethroughr	   )
setdefaultr   r0   _place_notify)r   kwargsr3   r!   r"   r   	  s    zCmfTask._place_notifyc                 O   s$   t jj|ddgd}| j| | S NrW   z
members.idr5   )r   CmfListrK   r.   remove)r   Zsrc_list_idargsr   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 r   )r   r   rK   r.   append)r   Zdst_list_idr   r   Zdst_listr!   r!   r"   copy_to_list  s    zCmfTask.copy_to_listc                 C   s   t j|j| d | S )N)r<   )r   CmfActiveEntityFilterrK   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   rK   r   r_   r   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_idTrC   u   Укажите to_idu(   Не могу перместить из u&   Не могу перместить в )r;   r   r   Zget_cls_by_tuuid_strr   r   r   r   r   r   r   )r   Zfrom_idZto_idr   r   Zfrom_clsZto_clsr!   r!   r"   move&  s$    





zCmfTask.moveFc                 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   #№ORrX   ILIKEaliasz%"z"%)filterr   T)lstripr   ZCmfTagrK   rX   r   r_   r   )r   	only_namectxr   tagr!   r!   r"   _process_tag_tokenG  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   rX   r   %Zloginr   )	
startswithr   rg   r   	CmfPersonrK   rX   r   r%   )r   r   r   r   Z_filterpersonr!   r!   r"   _process_responsible_tokenl  s*    

z"CmfTask._process_responsible_tokenu   Январьu   Февральu   Мартu   Апрельu   Майu   Июньu   Июльu   Августu   Сентябрьu   Октябрьu   Ноябрьu   Декабрь)            r            	   rj         c                 C   s(   |  }|  }|d| d| fkS )N#   №)lower)r   stringZhashtagr!   r!   r"   hashtag_cmp  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   rk   )_monthsitemsr   r*   rX   r9   rz   r   r{   r|   replacemonthr   r/   r   Zyearr   )	r   r   r   r   Z	month_idxr   r/   r   r   r!   r!   r"   _process_month_token  s>    
zCmfTask._process_month_tokenc                 C   s   | j dd dS )rp   T)r   N)_calc_from_namer(   r!   r!   r"   rl     s    zCmfTask._calc_namec                 C   s  | 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|| _ | jdkr| j r| j jdsd| j pd | _ d S )N z.,;:?!r   Fr   .c                 S   s   | j jS r=   )rX   r   )r   r!   r!   r"   <lambda>      z)CmfTask._calc_from_name.<locals>.<lambda>)keyTr   r
   rA   ZEpiczEpic 1)rX   r   r/   r_   r%   r   split	enumerater   striplocalscopyr   r   r   r   extendrg   rstripsortedr   r   joinrJ   r   )r   r   rX   Zname_tokensZundefined_tokensidxtokenr   r   Zneed_dotZdot_token_posr   r   r!   r!   r"   r     s\    


zCmfTask._calc_from_namec                 C   sF   | j js| jsd S | jdkr$d| _n| jdkr6d| _n| j | _d S )Nr@   listz
pfeed.basepost)rI   r   r*   rJ   ui_view_formZui_namer   r(   r!   r!   r"   _calc_ui_view_form
  s    

zCmfTask._calc_ui_view_formc                    sJ   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dg}t   | S )Nzparent.project_typezparent.auto_alarm_datezparent.logic_prefixzparent.activity.prefixr>   rL   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_levelrv   ru   cmf_modified_byrS   Ztimetracker_historyhas_child_tasksrH   rE   )r0   save_preload_fields)r   r   r3   r!   r"   r     s<    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s| j
D ]}|jdkr|| _ qq| js| j
D ]}|jdkr|| _ qq| j
jr4| jr4| dg | jjdkr4t| j
jt| j
j D ]}|jdkr|| _ q4q| jjrb| jrb| j| j
krb| j
| j | j
jrt| j
jt| j
j D ]0}|jdkrtd|j  d| j  dd	d
 q|   |   |   | jjr| jdkrtd| j dd	d
 t j||}| j
jrttjj dD ]&}t| |jr"ttjj  qJq"| j jrv| j rv| j jdkrvttj!j | 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_sprint	list.basezmain_list.logic_prefixr	   uM   Нельзя добавить задачу в Закрытый список "z" - ""TrC   )taskr   r   Zganttu   Вид отображения ua    еще не поддерживается, используйте "task", "list", "post", "gantt")r+   r   r_   r%   r/   rt   rA   r   )priority)+rX   r   r   rO   rR   r?   r   r   r7   r   r.   rS   setr9   r8   rJ   r;   r   r   r   _calc_logic_type_change_guard_calc_gantt_path!_calc_parent_task_has_child_tasksr   r0   r   Zcmf_deferred_taskr   r   recalculate_cachegetattrr   r>   r   r_   r   r   Zhook_task_tags_changedZ_clear_notifyr   r   rW   Z_update_opened_notifies)	r   r   r   r   Zremoved_listlZappended_listZself_instance
field_namer3   r!   r"   r   6  sn    







"

 $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 )NrX   r   !=r	   r   rG   Ztrashr   ra   =r   object_fieldsr   r   order_by)rK   r   r0   field_options_list)clsrelation_field_namer   r   r   r   r   ra   r3   r!   r"   lists_options_list  s2    

   zCmfTask.lists_options_listc                 K   sb   |sg }|r,| dd r,|dd| dgg}|ddddgdddggg}| j|f||||d|S )Nra   r   r   rJ   r   r   r   )rK   r   r   r   r   r   r   r   r   r!   r!   r"   main_list_options_list  s    zCmfTask.main_list_options_listc                    sp   |sg }|r,| dd r,|dd| dgg}| dd sR|ddddgdddggg}t j|f||||d|S )	Nra   r   searchr   rJ   rA   rB   r   )rK   r0   r   r   r3   r!   r"   parent_task_options_list  s    z CmfTask.parent_task_options_listc                    s   |dkr$| j |f||||d|S |dkrH| j|f||||d|S |dkrl| j|f||||d|S t j|f||||d|S )Nr.   r   rS   r>   )r   r   r   r0   r   r   r3   r!   r"   r     s*        zCmfTask.field_options_listT)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+   )rY   r   r	   zAuto task reopenu'   Переоткрываем задачу)r   textNdefault_projectr5   zNew auto task for r   z
) project 
r   )rY   rX   r   r%   rq   r   r   r   )printhashlibZmd5encodeZ	hexdigestr   r   rK   r   ry   Zget_default_statusr+   r   r2   Z
CmfCommentr   r   r   r   r   Zget_obj_by_tuuid_strr   rX   rY   rW   r   )rX   r   Z
extra_textr   responsible_idZcmf_owner_idra   _kwargsZtask_keyZ	task_hashZ	task_coder   r%   rq   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   rr   r   )rr   count)
r   r   r   rW   dictr   Zslistr   r   r   )r   r   r   r   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   rs   r%   	executorsrr   Tc                 S   s   g | ]}|j jqS r!   )rW   r   )r\   r<   r!   r!   r"   r^     s     z%CmfTask.notify_os.<locals>.<listcomp>F)r;   r   r9   rs   rW   r%   r  )r   	person_idr   r   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   rJ   ry   r6   r.   rI   rS   Z	scheme_wfZcalc_workflowr(   r!   r!   r"   _calc_workflow  s$    	zCmfTask._calc_workflowc                 C   sN   | j jsd S | jdkrd S | jjdkr2tddd | jjdkrJtddd d S )NrB   uI   У Подпроекта больше нельзя изменять типTrC   rA   uP   Тип Епик можно поменять только на Подпроект)rI   r   rJ   r9   r   r(   r!   r!   r"   r   *  s    
z%CmfTask._calc_logic_type_change_guardc                 C   sB   | j js*| jjr&| jdks*| jjdks*d S |   | | j  d S )Nr@   )r>   r   rI   rJ   r9   _calc_cache_branch_gantt_path_recalc_gantt_pathr(   r!   r!   r"   r   5  s    
zCmfTask._calc_gantt_pathr   c                 C   sV  |dkrt ddd |rx|dddg | j|jkr<|j| _| j|jkrP|j| _|jdkrh|| _d | _n|jd	krx|| _tjj| d
dddddgdD ]}d}| jd	kr| |_d}nL| jdkr| |_d |_d}n0|j| jkr| j|_d}|j| jkr| j|_d}|jr&|	|  |j
j|j
jkr&d}|r8|jdd |jr|jd |d d qd S )Nd   uM   DEV: Защита от рекурсии: _recalc_gantt_path: if r_count > 100TrC   rE   rH   rJ   rB   rA   cache_branch_gantt_pathr>   r   )r>   r   Fr   r   )r>   r_count)r   r;   rE   rH   rJ   r   r   r   r   r  r
  r8   r9   r   r  )r   r>   r  ZchZ	need_saver!   r!   r"   r  A  sH    

 


zCmfTask._recalc_gantt_pathc                 C   s|   | j sd | _d S |s(| ddg | j}|s6g | _d S |jj}|d krRtddd ||jj|jj|jj|j	jdf| _d S )Nz#parent_task.cache_branch_gantt_pathzparent_task.logic_prefixzODEV: WARNING: _calc_cache_branch_gantt_path: if cache_branch_gantt_path is NoneTrC   )rW   rY   rX   rJ   )
r   r
  r;   r>   r   r   rW   rY   rX   rJ   )r   r>   r
  r!   r!   r"   r  h  s$    z%CmfTask._calc_cache_branch_gantt_pathc                 C   s   | j jsdS | j jrH| dg | j jsHd| j _| j   | j jdd | j jrtj	j
dd| j jgdd| jggd	}|sd
| j j_| j j  | j jjdd dS )u   
            Рассчет has_child_tasks
            должен вызываться после _calc_parent_task
        Nzparent_task.has_child_tasksTr   r>   r   rW   r   r   F)r>   r   re   r;   r   r  r   r9   r   r   rK   rW   )r   Zhave_childsr!   r!   r"   r     s    
$
z)CmfTask._calc_parent_task_has_child_tasks   Изменена задача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_ownerr}   rs   r   rq   r   <   )r  rX   msgrr   r   )r   notify_namer   )r*   r;   r}   r~   r   rs   rW   r   r   rq   ra   	type_namer   r   r0   all_place_notify)r   r   r   r  r   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_attachmentsrW   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,   rz   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 rJ   r5   ztask.ticketzhelpdesk_mail_notification.html)r;   rJ   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   rt   r   )r0   _get_field_log_level)r   r   r   r   r3   r!   r"   r    s    zCmfTask._get_field_log_level   Добавленоc                 C   s   t j| |||S r=   )r   rN   Ztimetracker_task_change_time)r   rP   rQ   r   r!   r!   r"   timetracker_change_time  s    zCmfTask.timetracker_change_timer  )Z	only_onceZsoft_time_limitr   c               	   K   s   t j}d}d}|jddgdD ]}|d7 }|jdd|gd}|j|kr|d7 }td	|j d
| d|j  ||_|jdd |jj	|jj	d}t
d|j | t
d| qtd| d| d |S )u   Актуализация кеша кол-ва задач в епике (нужно ли для подпроекта? Вроде как нет).r   rA   cache_child_tasks_count)rJ   r   r   r>   r   r   zUpdate cache_members_count z -> r
   Tr   )Znode_idZelements_countztree-node-count-changes-ztree-node-count-changeszRecalculate r   z lists caches)r   r   r   r   r  r   debugrW   r   r   Zcmf_emit_event)r   r   Ztotal_countZ
calc_countZcmf_epicZ
real_countZ
event_datar!   r!   r"   r     s     
 zCmfTask.recalculate_cache)NN)F)F)F)F)NNNN)NNNN)NNNN)NNNN)NNNNNN)N)r   )N)Nr  )T)r  )=__name__
__module____qualname__r#   r)   r1   r:   r?   rM   rO   rR   rU   rc   r   rh   rm   rn   ro   rw   rx   r   r   r   r   r   r   r   r   r   r   r   rl   r   r   r   r   classmethodr   r   r   r   staticmethodZ
celery_appr   r   r  r  r  r   r   r  r  r   r  r  r  r  r  r  r   __classcell__r!   r!   r3   r"   r      s   $&	"
	A
a<  
!
%

*
=!V                            
          -
'
#


r   )rz   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   