U
    Vc                     @   sl   d dl 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)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	 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dcd)d*Zddd+d,Zded-d.Zd/d0d1d2d3d4d5d6d7d8d9d:d;Zd<d= Zdfd>d?Zd@dA ZdgdBdCZ fdDdEZ fdFdGZ e!dh fdHdI	Z"e!didJdKZ#e!dj fdLdM	Z$e%e&j'dNdOdkdPdQZ(e%dldRdSZ)dTdU Z*dVdW Z+dm fdYdZ	Z,d[d\ Z-dnd]d^Z. fd_d`Z/ fdadbZ0  Z1S )o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!   r0   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oldr/   _calc_activityload_fields)r   Ztmp_activityobjr2   r    r!   r9   Y   s:    


zCmfTask._calc_activityc                    s8   | j r| j j | _d S t   | js4tj|  d S N)parent_taskr   r&   r/   _calc_parentr   r   Z_calc_task_parentr'   r2   r    r!   r>      s    
zCmfTask._calc_parentc                 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   r@   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 rB   rF   rG   r    r    r!   rJ      s     tags
is_checked	parent_idactivity_id)r/   get_cache_fields_jsonr-   rK   rL   rM   rN   )r   retr2   r    r!   rO      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   r5   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   rR   rS   rX   rW   r   r    r    r!   
_calc_plan  s"    zCmfTask._calc_planc                    s0   t    | jr | jj|  ntj|  dS )u?    Ф-я вызывается из базового класса N)r/   _calc_statusr   r   Z_calc_task_statusr   r   r'   r2   r    r!   rZ   +  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   r\   r-   r   r*   waiting_forr5   r   approvedr)   r   approve_forapprove_for_placer   r%   r:   r8   r7   r'   r    r    r!   _calc_waiting_for5  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)rV   i  )r/   _calc_deadliner+   r   workflowZdefault_deadline_shiftr&   r5   r$   r   datetimeZ	timedeltar   timezoneutcZperiod_next_dater8   r7   r   cmf_created_atager\   gcurrent_person)r   Z
days_shiftshiftr   r2   r    r!   rc     sP    







zCmfTask._calc_deadlinec                    s    | d| jdk t jf |S )NZstrikethroughr   )
setdefaultr   r/   _place_notify)r   kwargsr2   r    r!   rn     s    zCmfTask._place_notifyc                 O   s$   t jj|ddgd}| j| | S NrC   z
members.idr4   )r   CmfListgetr-   remove)r   Zsrc_list_idargsro   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 rp   )r   rq   rr   r-   append)r   Zdst_list_idrt   ro   Zdst_listr    r    r!   copy_to_list  s    zCmfTask.copy_to_listc                 C   s   t j|j| d | S )N)r;   )r   CmfActiveEntityFilterrr   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_tagr4   T)Z	only_data)r   rx   rr   r{   rK   rs   save)r   ry   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   rq   ru   rx   r}   rw   rz   )r   Zfrom_idZto_idrt   ro   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   #№ORrD   ILIKEaliasz%"z"%)filterr   T)lstripr   ZCmfTagrr   rD   r   rK   rv   )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   rD   r   %Zloginr   )	
startswithr   rR   r   	CmfPersonrr   rD   r   r$   )r   r   r   r   Z_filterpersonr    r    r!   _process_responsible_token5  s*    

z"CmfTask._process_responsible_tokenu   Январьu   Февральu   Мартu   Апрельu   Майu   Июньu   Июльu   Августu   Сентябрьu   Октябрьu   Ноябрьu   Декабрь)            r            	   rU         c                 C   s(   |  }|  }|d| d| fkS )N#   №)lower)r   stringZhashtagr    r    r!   hashtag_cmpa  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   rV   )_monthsitemsr   r)   rD   r8   re   r   rf   rg   replacemonthr   r.   r   Zyearr   )	r   r   r   r   Z	month_idxr   r.   rl   r   r    r    r!   _process_month_tokeng  s>    
zCmfTask._process_month_tokenc                 C   s   | j dd dS )r[   T)r   N)_calc_from_namer'   r    r    r!   rW     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<   )rD   r   )r   r    r    r!   <lambda>      z)CmfTask._calc_from_name.<locals>.<lambda>)keyTr   r	   )rD   r   r.   rK   r$   r   split	enumerater   striplocalscopyr   r   r   rv   extendrR   rstripsortedr   r   join)r   r   rD   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                    s@   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_levelra   r`   cmf_modified_byr?   )r/   save_preload_fields)r   r   r2   r    r!   r     s2    zCmfTask.save_preload_fieldsc           	         sX  | j jr|   |   | jj }r8t|dr8||  | jjrt| j	rtt
| jjt
| jj D ]}|| j	kr^d | _	q^| 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rt| j	jrt| j	jrt| j	j| jkrt| j	j| jkrt| j| j	j | j	jr| j	r| j	| jkr| j| j	 t j||}| jjrttjj dD ]&}t| |jrttjj  qq| jjr$| jr$t| jjtjr$| j| j | jjrT| jdkrT| tjj  | j!dd |S )Nhook_task_savelist.agile_epicz	list.base)r*   r   rK   r$   r.   r_   r   r   )priority)"rD   r   r   r>   r   r   r6   r   r-   r?   setr8   r7   rs   logic_prefixrv   r/   r|   Zcmf_deferred_taskr   rq   Zrecalculate_cachegetattrrx   rK   r   r   Zhook_task_tags_changedr   Z_clear_notifyrj   rk   rC   Z_update_opened_notifies)	r   rt   ro   r   Zremoved_listlZappended_listZself_instance
field_namer2   r    r!   r|     sP    


 

$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 )NrD   r   z!=r   r   Zsys_typeZtrashr   rM   =r   object_fieldsr   r   order_by)rr   rv   r/   field_options_list)clsrelation_field_namer   r   r   r   ro   rM   r2   r    r!   lists_options_list1  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   )rr   r   r   r   r   r   r   r   ro   r    r    r!   main_list_options_listH  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   r?   )r   r   r/   r   r   r2   r    r!   r   Y  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*   )rE   r   r   zAuto task reopenu'   Переоткрываем задачу)r   textNdefault_projectr4   zNew auto task for r
   z
) project 
r   )rE   rD   r   r$   r\   r   r   r   )printhashlibZmd5encodeZ	hexdigestr   r   rr   r   rd   Zget_default_statusr*   r   r1   Z
CmfCommentr|   r   r   r   r   Zget_obj_by_tuuid_strr   rD   rE   rC   r   )rD   r   Z
extra_textr   responsible_idZcmf_owner_idrM   _kwargsZtask_keyZ	task_hashZ	task_codetaskr$   r\   r   r    r    r!   	auto_taskc  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   r]   r   )r]   count)
r   r   listrC   dictr   Zslistr   rm   r   )r   r   rt   ro   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   r^   r$   	executorsr]   Tc                 S   s   g | ]}|j jqS r    )rC   r   )rH   r;   r    r    r!   rJ     s     z%CmfTask.notify_os.<locals>.<listcomp>F)r:   r   r8   r^   rC   r$   r   )r   	person_idrt   ro   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   rd   r5   r-   Z
logic_typer?   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_ownerrh   r^   r   r\   r   <   )r   rD   msgr]   r   )r   notify_namer   )r)   r:   rh   ri   rn   r^   rC   r   r   r\   rM   	type_namerv   r   r/   all_place_notify)r   r   r   r   ro   r   r   r2   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_attachmentsrC   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+   r4   r   )r:   r.   r+   re   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   r4   ztask.ticketzhelpdesk_mail_notification.html)r:   r   r/   +get_default_mail_notification_template_namer'   r2   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   r_   r   )r/   _get_field_log_level)r   r   rt   ro   r2   r    r!   r     s    zCmfTask._get_field_log_level)NN)F)F)F)F)NNNN)NNNN)NNNN)NNNNNN)N)Nr   )T)2__name__
__module____qualname__Zmenu_tree_show_objr"   r(   r0   r9   r>   rA   rO   r   rS   rX   rY   rZ   rb   rc   rn   ru   rw   rz   r}   r   r   r   r   r   r   rW   r   r   r|   classmethodr   r   r   staticmethodZ
celery_appr   r   r   r   r   r   r   r   r   r   __classcell__r    r    r2   r!   r      s   $&		A
a<  
!
%

*
9F                     	
          -#

r   )re   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   