U
    Vf                    @   s   d dl Z d dlZd dlmZ d dl mZ d dlmZ 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ZG d	d
 d
ejjjjejjjjZdS )    N)defaultdict)	timedelta)Decimal)FileStorage)relativedelta)*)CmfTUUIDc                       s:  e Zd Zedd fdd
Zedd fdd
Zedd fdd
Zed	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Z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( Zd)d* Zd+d, Z fd-d.Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z fd9d:Z fd;d<Z d=d> Z! fd?d@Z"dAdB Z#dCdD Z$dEdF Z%dGdH Z&ddIdJZ'ddLdMZ(ddNdOZ)ddPdQZ*dRdSdTdUdVdWdXdYdZd[d\d]d^Z+d_d` Z,d dadbZ-dcdd Z.d!dedfZ/dgdh Z0didj Z1dkdl Z2dmdn Z3 fdodpZ4 fdqdrZ5dsdt Z6dudv Z7 fdwdxZ8dydz Z9d{d| Z:d}d~ Z;dd Z<dd Z=e fddZ>e?@de?jAZBed"ddZCdd ZDdd ZE fddZFd#ddZGdd ZHdKdddZIdKdddZJdd ZK fddZL fddZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUd$ fdd	ZVed% fdd	ZWed& fdd	ZXed'ddZYed( fdd	ZZed)ddZ[ed* fdd	Z\e]e^ddd+ddZ_e]d,ddZ`ddÄ Zaddń ZbddǄ Zcd-ddʄZdd.dd̄Zedd΄ ZfddЄ Zgdd҄ ZhddԄ Ziddք Zjdd؄ Zk fddڄZl fdd܄Zmd/dd߄Zne]e^dddddd Zoe]dd Zpe]d0ddZqe]e^ddddddd Zrddesd fddZteddKddd fdd
Zued1 fdd	Zvedd ZwdKdKdKdKdexeyeyeyeyd fddZzdd Z{e| fddZ}ed2d dZ~dd Z fddZd3 fdd	Zedddd	d
Z fddZdd Zdd Ze]e^dddddd Z fddZed4 fdd	Zed5exd fddZ  ZS (6  CmfTaskN)include_systemc                   s   |s| dd t j||S NsystemF)
setdefaultsuperlistclsr
   argskwargs	__class__ !./modules/task/models/cmf_task.pyr      s    zCmfTask.listc                   s   |s| dd t j||S r   )r   r   countr   r   r   r   r      s    zCmfTask.countc                   s   |s| dd t j||S r   )r   r   slistr   r   r   r   r       s    zCmfTask.slistc                 O   st   t jf ddi|}|j|_d|_|jdd |jrZ|jjd|ddsZd |_d |_|  |	  |
  d|jiS )	NcodeZdummyT)Zskip_project_perms_checkPPP-TSK-CREATEF)objraise_errorid)modelsr	   r   r   is_dummy_calc_projectprojectcheck_project_role_accessparentZ_calc_default_fieldsave)r   r   r   Z
dummy_taskr   r   r   create_dummy_task'   s    zCmfTask.create_dummy_taskc           
      C   s  |  |  dg  | js.td| j dd tjj| dddD ]}d |_|	  q@| j
D ]$}t| j
| tj
jrZt| |g  qZ| j	dd | jr| jj}d | _| j	dd |j| tjj| ddD ]}|j| qtjjdd	d
| gdd
| ggddD ]}|j| qtjj| dd}|D ]}|j| q"tjtjfD ](}|j| ddD ]}	|	j|	 qTqBtjjdd| gddD ]}	|	j|	 q| j|  d S )Nr       Не dummy task Tabortparent_taskinclude_deletedr
   	only_datataskr,   ORout_link==in_linkfilterr,   )r$   r,   r   =)load_fieldssave_preload_fieldsr    	cmf_alertr   r   r	   r   r+   r%   fields
issubclasscmfZ
CmfM2MBasesetattrop_gantt_taskvalueZdpdeleteCmfShadowLinkCmfRelationOptionCmfTimeTrackerHistoryCmfListHistoryOTRCmfListHistoryRTECmfStatusHistory)
selfZsubtask
field_namegtlinkreltt_history_listtthZmodelhr   r   r   delete_dummy_taskC   s@    



zCmfTask.delete_dummy_taskc                 C   s   |  ddddddddd	d
g
 | jjr0| jj| _| jjrB| jj| _| jjrb| j| jjk rb| jj| _| jjrt| jj| _| jjr| jjD ]}|| jkr| j| q| jjr| jj	rt
j
jt
jjd| jj| jj	  }| jr| j|kr|| _| jj	r| j	  d S )Nzcloned_from.parentzcloned_from.listszcloned_from.logic_typezcloned_from.priorityzcloned_from.deadlinezcloned_from.alarm_datezcloned_from.responsiblelistsprioritydeadlineZtz)r8   Zcloned_fromr$   
logic_typerR   responsiblerQ   appendrS   
alarm_datedatetimenowtimezoneutcset_now)rH   lZdeadline_minr   r   r   #_save_dummy_task_sync_from_templateo   s8    
     




"z+CmfTask._save_dummy_task_sync_from_templatec                 C   s   |    | js"td| j dd | D ]\}}|| |< d| | _q*d| _|   d| _| j| jkrnd | _ntd| j dd | j	r| 
  |   | j| j| j| jdS )Nr'   Tr(   Fu)   Выставлен код у dummy-task: )r   r   name	parent_id)save_preparer    r:   r   items
is_changedZ_load_changed_fieldsis_newr   cloned_from_idr_   r%   r`   ra   )rH   Zchanged_fieldskvr   r   r   save_dummy_task   s(    zCmfTask.save_dummy_taskc                 C   s   | j std| j dd | jjrH| jjrH| jtjkrHtd | jj| _dt_| 	  | 
  |   |   |   |   |   |   |   |   |   |   |   |   |   |   | jdddddd | S )Nr'   Tr(   um   Пожалуйста сохраните задачу перед изменением постановщикаF)r.   notifyemitauditZ	no_reload)r    r:   r   	cmf_ownerrd   oldgcurrent_userTEXCOM_ENABLE_GROWCACHE_HACKr!   _calc_parent_task!_calc_parent_task_has_child_tasks_calc_gantt_path_calc_gantt_task_calc_activity_calc_scheme_wf_calc_logic_type_calc_workflow_calc_status_calc_parent_logic_prefix_calc_ui_view_form_calc_fix_versionscalc_history_calc_wf_simple_logicZ_calc_perm_security_levelr%   rH   r   r   r   _dummy_save   s0    	
	zCmfTask._dummy_savec                 C   sD   d}| j dddgdd| jggdgdd	}|r@t|jd
d }|S )Nr   z
SIMILAR TOz
%-[0-9]+\Zr"   r7   -cmf_created_atT)r6   order_byr,   -)sget
project_idintr   split)rH   Z
max_numberZlastr   r   r    _get_current_code_number_from_db   s    z(CmfTask._get_current_code_number_from_dbc                 C   s   t j}d}| jr| jj}d| j d| }| j d| d}|jj|dd}|  z2||rl||}n|  d }||| W 5 z|  W nF tj	j
k
r } z$td| d|j d	|j  W 5 d
}~X Y nX X | S )uN    Высчитывает следующий номер для кода
        Z	NOPROJECTznext_code_number-r   z.lock   )timeoutzlock release error z, lock_name z
, timeout N   )APPZREDIS_DBr   r@   
class_nameredislockacquirerelease
exceptionsZ	LockErrorro   debugr`   r   existsZincrr   set)rH   Zredis_dbsuffixkeyZlock_keyr   enext_code_numberr   r   r   r      s$    
4zCmfTask.next_code_numberc              	   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
isinstancer$   r@   r   
CmfProject_calc_list_plan_intervalrX   rd   r:   captionr=   r;   CmfDateTimerZ   plan_end_daterH   list_plan_start_date_maxlist_plan_end_date_minr   r   r   _calc_alarm_date_list  s,    

$zCmfTask._calc_alarm_date_listc                 C   s   | j r| jjs| jjsd S | j jr&d S | jD ]0}|js<|jr,|jrJ|j| _ |jrX|j| _ q^q,| j s| jr| jjjdkr| jj 	 r| jj | _ d S Nr   )
rV   r$   rd   
componentsZdefault_responsibleZdefault_ownerrm   r@   r   load)rH   compr   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 rtjr| j  d S r   )re   rX   rd   statusrS   activityrQ   plan_start_dater   r   _calc_alarm_dater$   r@   r   Zauto_alarm_dater   r   rZ   ro   import_moder]   r   r   r   r   r   :  sR    


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 jdgd}q|s| jr| jd j jdgd}|r|| _ | j st
   dS )u   
        Вычисляем вид деятельности
        Метод вызывается из базового класса.
        :return:
        Nr   r   r;   r   )r   rd   re   r$   rQ   is_nullhasattrr   newrn   r   rv   )rH   Ztmp_activityr   r   r   r   rv   _  s6    

zCmfTask._calc_activityc                 C   s   d S Nr   r   r   r   r   _calc_parent  s    zCmfTask._calc_parentc                 C   s   | j jr&| j jr&d | _| jdd d S | j js8| j r8d S | j r| j jr| j | j jkr| jr|| j j  | j j| _| jdd ddg}| | | jsd S | j	  t
jjdd| g|d}|D ] }|j | j kr| j |_ |  qd S )NTr-   r$   r?   r+   r7   r6   r;   )r$   r   rn   gantt_projectr%   main_gantt_projectr   r8   r?   Ztask_parent_is_changed_hookr   r	   r   rH   r;   Zchild_tasksr0   r   r   r   _do_parent_is_changed  s*    


zCmfTask._do_parent_is_changedc                 C   s  | j js$| jjs$| jjs$| jjs$d S | jr| jjr| j| jjkr| jddg | jjdkrd}| jj| _|   t	j
| |dd  t| d S | jjrd S | j jr| j r|  }|r|| jkr|ddd	d
g || _|   d S | jjr| jrd }d }| ddg | jjr8| jjjr8| jjj}| jjj}|r| jspd}|| _t	j
| |dd  |   d S |rd}|| _t	j
| |dd  |   d S d S )Nr$   logic_prefixtask.gantt_projectu   SimpleLogic: в задаче установлен проект равный проекту родительской задачи   r$   text	log_levelrm   cmf_owner_assistantsr   r   8responsible.primary_role.structural_project.default_listz1responsible.primary_role.structural_project_forceu   SimpleLogic: Задача добавлена в Структурный проект Главной роли исполнителяu   SimpleLogic: Проект сменен, т.к. в Главной роли исполнителя указано менять проект)tree_parentrd   rV   r+   r$   ra   r8   r   rb   r   
CmfCommentr%   r:   Z_node_parentr9   primary_rolestructural_projectZstructural_project_force)rH   Z	sl_reasonr$   Zstruct_projectZstruct_project_forcer   r   r   _HACK24052023_calc_parent  s`    


z!CmfTask._HACK24052023_calc_parentc                 C   sX  | j r| jjs| jjsd S | jjr| jdkr| j r| jr| jjr| dg | j | jkr| j j| jkrtjj| jddgd| _ | j s| j| _ d S | jjr| jjdkr| jdkrtjj| jddgd| _ | j s| j| _ | j	jrB| j rB| jdkrB| jjdkrB| j
jdd | j
r<td | j
D ]}| j |_ |  q$d | _ | jd	krTd | _ d S )
N	task.epictask.subprojectztree_parent.parentepicZtree_hidden)r$   sys_typer;   T)r,   u   Скрываем задачу в дереве проекта, её дочерние элементы вставляем вместо неёr   )r   r   rd   r$   rn   r8   r   Z	CmfFoldergetrU   Z
tree_nodesr   r:   r%   )rH   childr   r   r   _calc_tree_parent  s\    



zCmfTask._calc_tree_parentc                 C   s   | j rD| j}|rD|jjdkrD|ddg |jdkr<|| _qD|j}q| jjr| jr| jj  | jr| jjjdkr| jjdkr| j| _| j	jr| jdkrt
ddd	 | j	| _| jjr| jdkrt
d
dd	 | j| _d S )Nr   r   r   r   r	   ztask.subu2   У подзадач нельзя менять EpicTr(   u@   У подзадач нельзя менять Подпроект)re   r   r@   r   r8   r   r+   rd   r   r   r:   
subproject)rH   Ztmp_tree_parentr   r   r   rr   !  s,    



zCmfTask._calc_parent_taskc                 C   s&   | j r
d S | jjsd S tj|  d S r   )re   r   rd   r   CmfTimeTrackerZtimetracker_task_change_statusr   r   r   r   _calc_timetracker=  s
    zCmfTask._calc_timetrackerc                 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   )re   r   rd   r$   r+   	main_listZ_load_perm_fieldsr   r@   r   ZCmfDocumentperm_parent)rH   r   r   r   r   _calc_perm_parentG  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 r   r`   r   Zto_json.0ir   r   r   
<listcomp>c  s     z1CmfTask.get_cache_fields_json.<locals>.<listcomp>rQ   c                 S   s   g | ]}| d ddgqS r   r   r   r   r   r   r   d  s     tags
is_checkedra   activity_id)r   get_cache_fields_jsonrQ   r   r   ra   r   )rH   retr   r   r   r   a  s    



zCmfTask.get_cache_fields_jsonc                 C   s   d }d }| j D ]X}|jsq|jdkr&q|jjrF|d ks@|j|krF|j}|jjr|d ks`|j|k r|j}q|s||r|tjj	 }||fS Nr   )
rQ   Zaffect_gantt_taskr   r   is_not_nullr   r=   r;   r   rZ   )rH   r   r   Zw_listr   r   r   r   j  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 )Nr   uP    установлена в соответствии с планом списка)	rQ   rd   lenr   r   rX   r   r:   r   )rH   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   План сдвинут в соответствии с будильником)	rX   rd   r   r   r   daysr@   r:   
_calc_name)rH   Z	date_diffr   r   r   _calc_plan_nolist  s2    

		zCmfTask._calc_plan_nolistc                 C   sb   | 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)
rQ   rd   re   rX   r   r   r   r   r   r   r   r   r   r   
_calc_plan  s     zCmfTask._calc_planc                 C   sL  | j s"| jjs"| jjs"| jjs"d S | jjr4| j s4d S | jrH| jjjdkrfd| _tj| ddd	  d S | 
 }| js|jsd| _tj| d|j dd	  d S | jr|jr| jr| jjrd| _tj| ddd	  | j| jj ks| jj| jjkr tj| jkr d| _tj| d	dd	  | j rH| jjrH| jrH| jsHd| _d S )
Nr   Tu~   SimpleLogic: Задача согласована автоматически, т.к. это Непроектная задачаr   r   u   SimpleLogic: Задача согласована автоматически, т.к. согласование отключено в Fu   SimpleLogic: Выполнен сброс согласования, т.к. сменился Постановщик или Проектu   SimpleLogic: Задача согласована автоматически, т.к. постановщик - руководитель.)re   approvedrd   rm   r$   r@   r   r   r   r%   _get_sl_optionssl_task_need_approveZsl_controller_strr   r   ro   current_personZ
cmf_importZ
is_defined)rH   
sl_optionsr   r   r   _calc_approved  sV    



$

"zCmfTask._calc_approvedc                    s   t t  }| ddg | jD ]&}||j |jD ]}|| q8q"| jjrt | jj	t | jj
 D ]4}|ddg ||j |jD ]}|| qqj| jr| jjds| j D ]}|| qt|S )Nzlists.cmf_ownerzlists.cmf_owner_assistantsrm   r   zCmfProject:)r   r   
get_ownersr8   rQ   addrm   r   rd   rn   r   r$   ra   r@   
startswithr   )rH   r   r   Zownerslstownerr   r   r   r   #  s     


zCmfTask.get_ownersc                    s&   | j r
d S | jdkrd S t   d S r   )waiting_forr   r   _calc_waiting_forr   r   r   r   r   ;  s
    
zCmfTask._calc_waiting_forc           	      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 tj	
drLdS |  }| j}d}| jr| jjjdkrd}| jj }|r| js| j jjdkr| jj| _d| _| jjr| jr| jdkrd| _d| _| jdkr| j jjdkrd| _d| _|r8| jjr8| jr8|jr8|jr8tj| j kr8td	dd
 | jr| jjrl| jj| jksd| jjsl| j| _| jjr| jj| jkr| j| _| jjr| jr| jjr| jjj | jkr| j| jks| js| jj| _| jjr| jjs| jj| _| jjr| jsd| _| jjrD| jp*|| _| j jdkrD| j| _| jrPdS d}| jjr| jjsr| jjs| jjr| jjsd}| j jr| j jr| j jrd}| jjrd}| jjrd}|sdS | j jjdkrD| j jjdk}|s| jjddds| j j| jdk}|rD| j jjdkr@| jp<|| _| js| j|kr|sf|| _d| _|| _tj | d|j! ddd"  | jjs| jjr| j|kr| jr| j| _tj | d| j ddd"  | jdkr|sd| _d| _| jr@| j|kr@| jr@| jr@| j| _tj | d| j ddd"  dS | j jjdkr|j#r| j$rtj%j&dd| gdddggd}|rtddd
 |j#s| j$rtj%j&dd| gdddggd}|rtd |j'r(| j(r(tj%j&dd| j(gdddggd}|s(| jd| j(_ | j("  td |rv|j)rvtj|  krv| j*sv| jjddd }|rv|| _ td! q| j jjdkrd| _| jdks| jrd| _d| _dS | j jjdkrd| j*r| jd| _ td" q| js| j+  | j jjdkr | j| j, kr | j+  | j| _| j| _d| _tj | d#| jj! d$| j j! d%dd"  dS | j jd&kr~| j jjd&kr| js|j-rtd'dd
 td( | j jjdkr| jp|| _tj | d)dd"  | j jjdkr| j|kr| jp|| _tj | d*dd"  | js(| j+  | j jjd&krr| j| j, krr| j+  tj | d+| j j! dd"  dS q~qdS ),uS   
            Ф-я вызывается из базового класса
        NimportFr   T	IN_REVIEWZapprove2Zapprove1_reviewu[   Только Владелец проекта может согласовать задачуr(   r   open)status_coder   )r   IN_PROGRESSZapprove3_notassigneduh   SimpleLogic: Задачу переключили на Постановщика/Руководителя(u   ), т.к. не указан Будильник. Установите будильник, чтобы задача отобразилась у Исполнителяr   r   uM   SimpleLogic: Задачу переключили на Исполнителя(u   ), т.к. указан Будильник.Установите будильник, чтобы задача отобразилась у Исполнителяr   r   r+   r7   r   !=r6   um   Для закрытия задачи необходимо закрыть все дочерние задачиu_   Вы закрыли задачу у которой есть Открытые подзадачиu}   Родительская задача закрыта автоматически т.к. закрыты все дочерние)r   u   Спасибо! Статус установлен в "Подтверждение закрытия", для проверки постановщиком или владельцем проектаu   Спасибо! Статус изменен на «Закрыто» т.к установлен флаг «Без подтверждения».uO   SimpleLogic: Задачу переключили на Постановщика(u   ), т.к. статус=''r  uT   Нельзя брать в работу несогласованную задачу.um   Внимание! Вы взяли задачу без согласования с руководителем.u^   SimpleLogic: waiting_for  установлен т.к. статус снижен в in_progressui   SimpleLogic: waiting_for установлен т.к. статус перешел из open в in_progressu[   SimpleLogic: будильник установлен т.к. статус сменен на ).r   rd   r   rV   rm   r$   rX   r   osenvironr   r   r@   r   r   r   status_typeapprove_forapprove_for_placeZsl_only_owner_approver   ro   r   r   r:   rn   r   re   r   workflowget_default_statusr   r   r`   r%   Z,sl_deny_closing_task_before_closing_subtaskshas_child_tasksr	   r   t%   sl_сlose_task_after_closing_subtasksr+   Zsl_task_only_owner_closeZ
no_controlr]   rZ   Zsl_deny_no_approve)	rH   r   Ztask_controllerZis_project_taskZ
need_transZsimple_logicZhas_unclosed_subtasksZ unclosed_subtasks_in_parent_taskZin_review_statusr   r   r   r   C  st   
 $2


	



 
$



*




zCmfTask._calc_wf_simple_logicc                    s   t    | jjs,| jjs,| jjs,| js,d S | jjr8d S |  }|j	d krNd S |j	}t
j|d}t
j
t
jj}| 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s| jjr
| js|| | _n$| jr| j|| kr|| | _n d S | js|| | _d S )N)r   i  )r   _calc_deadliner
  rd   r$   rX   re   rS   r   Zsl_deadline_shiftrY   r   rZ   r[   r\   cmf_created_atagerm   ro   r   r@   )rH   r   Z
days_shiftshiftrZ   r   r   r   r  ]  sP    



zCmfTask._calc_deadlinec                 O   s0   |  dg tjj|ddgd}| j| | S NrQ   r   z
members.idr   )r8   r   CmfListr   rQ   remove)rH   Zsrc_list_idr   r   Zsrc_listr   r   r   remove_from_list  s    zCmfTask.remove_from_listc                 O   s0   |  dg tjj|ddgd}| j| | S r  )r8   r   r  r   rQ   rW   )rH   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   CmfActiveEntityFilterr   Zadd_active_entity)rH   	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_tagr   Tr-   )r   r  r   r  r   r  r%   )rH   r  Zactive_entity_filterr   r   r   remove_from_filter  s
    zCmfTask.remove_from_filterc                 O   s>  |  dddg |s tddd |s0tddd t|}t|}|tjkrZ| | nH|tjkrp| | n2|tj	kr|| j
jjkrd | _
ntd| dd |tjkr| | n|tjkr| | nl|tj	kr(tj	j|d	gd
}| j
r | j
|kr td|j d| j
j ddd || _
ntd| dd | S )NrQ   r+   zparent_task.nameu   Укажите from_idTr(   u   Укажите to_idu(   Не могу перместить из r`   r   r;   u5   Нельзя переместить задачу в "u/   ", так как она находится в ""u&   Не могу перместить в )r8   r:   r   Zget_cls_by_tuuid_strr   r  r  r  r  r	   r+   r   r@   r  r  r   r`   )rH   Zfrom_idZto_idr   r   Zfrom_clsZto_clsZtarget_taskr   r   r   move  s4    






 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      #№@r1   r`   ILIKEaliasz%"z"%r   T)lstripr   ZCmfTagr   r`   rd   r   rW   )rH   	only_namectxr   tagr   r   r   _process_tag_token  s*    
	zCmfTask._process_tag_tokenc                 K   sz   |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 |sv|| _dS r  )r$  r   ZCmfLogicTyper   r`   rd   rU   )rH   r%  r&  r   ltr   r   r   _process_logic_type_token  s*    
	z!CmfTask._process_logic_type_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)#   №@r!     
user_localr3   Tr1   r`   r"  %Zloginr  )	r   r$  r   r   	CmfPersonr   r`   rd   rV   )rH   r%  r&  r   _filterpersonr   r   r   _process_responsible_token4  s*    

z"CmfTask._process_responsible_tokenu   Январьu   Февральu   Мартu   Апрельu   Майu   Июньu   Июльu   Августu   Сентябрьu   Октябрьu   Ноябрьu   Декабрь)r   r         r.           	   r         c                 C   s0   |  }|  }|d| d| d| fkS )Nr+  r,  r-  )lower)rH   stringZhashtagr   r   r   hashtag_cmp`  s    zCmfTask.hashtag_cmpc           	      K   s   |d }| j  D ]4\}}| }|d| d| d| fkr qLqdS |s| jsj|| jj krjd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,  r-  FTrT   r   r   )ZdayZhourZminutesecondZmicrosecondr<  )monthsr   )rA  r   )_monthsrc   r=  re   r`   rn   rY   rZ   r[   r\   replacemonthr   r   r@   Zyearr   )	rH   r%  r&  r   Z	month_idxrD  r   r  r   r   r   r   _process_month_tokenf  s>     
zCmfTask._process_month_tokenc                 C   s   | j dd dS )uG    Ф-я вызывается из базового класса
        T)r%  N)_calc_from_namer   r   r   r   r     s    zCmfTask._calc_namec                 C   s  t jjj}| jjs2| jjs2| jjr&|s2| jjs2d S | jjp<d}|	 }g }|rX|sXg | _t
|D ]`\}}| d}t  }	|	d= | jf |	rq`| jf |	rq`| jf |	rq`|| |s`q`q`g }d}
|r|| t|d }|| d||< |r,t| jdd d	D ]}d
}
|d|j  q|
rH|rH||  d7  < d|| _| jdkr| jr| jr| jjdgd | jr| jjs| jpd | _n,| jr| jjdsd| jpd | _n| jsd| _d S )N z.,;:?!rH   Fr   .c                 S   s   | j jS r   )r`   r@   )r'  r   r   r   <lambda>      z)CmfTask._calc_from_name.<locals>.<lambda>r   Tr+  r   r   add_object_typer   1ZEpiczEpic zEpic 1)ro   Zglobal_settingsZshow_task_title_tagsr@   r`   rd   r   r   rV   r   	enumerater=  striplocalscopyr*  r(  r4  rW   extendr   rstripsortedjoinr   re   r$   r8   rL  r   )rH   r%  Zname_tags_boundr`   Zname_tokensZundefined_tokensidxtokenr   r&  Zneed_dotZdot_token_posr'  r   r   r   rF    sj    



zCmfTask._calc_from_namec                 C   sX   | j js| jsd S | jdkr$d| _n0| jdkr6d| _n| jdkrHd| _n| j | _d S )N)r   gantt)r   ztask.gantt_subprojectr   z
pfeed.basepost)rU   rd   re   r   ui_view_formui_namer=  r   r   r   r   r|     s    


zCmfTask._calc_ui_view_formc                 C   s   |  ddddg | jsP| jrP| j dddg | jjdkrF| j| _n
| jj| _| js~| jdkr~| jr~| j dg | jj| _d S )	Nr$   r   r+   r   zgantt_project.op_gantt_taskr?   r   z main_gantt_project.op_gantt_task)r8   r   r+   r   r$   r   r   r   r   r   _calc_gantt_project  s    

zCmfTask._calc_gantt_projectc              	   C   sr  | j r| j jjdkr*| jdkr*tddd | j r>| j jjdkrX| jsTtj| d | _d S | j	s| j
r| j
ddg | j
jdkr| j
| _	n
| j
j	| _	| j	s| jd	kr| j j  | j j| _	| j	}|s| jdkr| }t  | jstj| d }|| _| j
js
| j	jr&|| j_	| j
| j_
| j  | jsd| j jrd| j rd| j jjdkrd| j | j_| j  W 5 Q R X d S )
Nr   r   r   r   u_   task.epic, task.subproject и task.gantt_project не могут быть без ПроектаTr(   r   r   r   r   )r$   r@   r   r   r:   r?   r   CmfGanttTaskcreate_gantt_taskr   r+   r8   r   r   cmfutildisable_aclrd   r%   re   r"   )rH   Zcur_gantt_projectr?   r   r   r   ru      sJ    







zCmfTask._calc_gantt_taskc                 C   s<   | j jr| j| j j| j j | jjs.| jjr8| j  dS )u   
        Изменяем счетчики Оперативной Гант-задачи при изменении задачи
        N)	r   rd   r?   Ztask_status_is_changed_hookrn   r   r   r   Ztask_plan_dates_is_changed_hookr   r   r   r   _calc_op_gantt_task_counters9  s    z$CmfTask._calc_op_gantt_task_countersc                    s  | j js,| jdkr,|  }|jr,tddd | js<t  S | j	sL| jsLd S t
 }| jddD ]6}|j|  kr^|jds^|jds^||j q^d|ksd	|kr6| jjs| jjr| jr| jjd
| dd | jjr| jjr| jj| jjkr| js| jjd| d d|kr"|d d	|kr6|d	 d|krx| jjd| d | jrn| jjd| jj| d |d d|kr| jjr| jjd| d |d d|kr| jjd| d |d d|kr| jjd| d |d d|krb| jjr.| jdkr.| jjdkr.| jjd| d n*| j jrX| jjd| d | jjd| d |d d|kr| jjd| d |d d|kr| jjd| d |d d|kr| js| jjr| jjd| d |d d|krB| jjd | d | jjD ]4^}}}|d!kr|jd"kr| jjd|| d q|d d#|krf| jjd$| d |d# |r|| jjd%| d d S )&Nr   ud   Редактирование запрещено, так как задача в статусе CLOSEDTr(   )rd   Zcache_Z_idr$   r"   r   )r   Zuse_new_projectzPPP-TSK-MOVEr  rV   zPPP-TSK-ASSIGNzPPP-TSK-ASSIGNABLE)userr   rm   zPPP-TSK-MODIFY-OWNERr+   rQ   r   zPPP-TSK-CLOSEzPPP-TSK-RESOLVEzPPP-TSK-TRANSITION
spectatorszPPP-VW-MANAGErS   zPPP-TSK-DEADLINErX   	executorszPPP-TSK-ASSIGN-EXECUTORSrW   r1  Zperm_security_levelzPPP-TSK-SET-SECURITYzPPP-TSK-EDIT)r   rd   r   r   Zsl_readonly_closed_taskr:   r"   r   check_edit_permre   r   valuesr   Zproject_perm_allow_fieldsr   endswithr   r$   r#   rn   r   r    r  rV   r@   rm   rX   re  Z_changes)rH   r   Zchanged_fields_to_checkZfieldZchange_actionZ
change_obj_r   r   r   rf  B  s    


&













$











zCmfTask.check_edit_permc                    sT   |  ddddddg | js.| js.| jtjkrP| jrF| jjd| d n
t 	  d S )	Nr   r"   rm   rQ   rV   re  zPPP-TSK-DELETEr  )
r8   r   r`   rm   ro   rp   r"   r#   r   check_delete_permr   r   r   r   rj    s    
  zCmfTask.check_delete_permc                 C   sb   | j s^| jjr^| jjs^| jr^tjjdd| jgddddgdddgggdD ]}| j|_|	  qHdS )u  
        При создании задачи - у нее не указывается имя сразу, но уже создается нотифай с пустым именем.
        Но нотифай по str-полям когда пусто меняется на имя - не создается и не обновляет информацию в созданных нотифаях.
        Поэтому мы сделал этот ХАК с нарушением слоёв.
        Zobj_idr3   r1   r   rG  Nr  )
re   r`   rd   rn   r   Z	CmfNotifyr   r   r   r%   )rH   Ztask_notifyr   r   r   _update_empty_task_notify  s    
z!CmfTask._update_empty_task_notifyc                 C   s   | j r| j jjdks| j jr d S d}| jjrZt| jjt| jj D ]}|j	dkrD|}qDqD|sbd S t| j}|D ]D}||kr~qp|j	dkrqp|j
dkrqp|j
dkrtd | j| qpd S )Nr   Flist.agile_sprintr   r  u\   Внимание! Задача перемещена из Запущенного списка)r$   r@   r   Ztask_allow_multiple_sprintsrQ   rd   r   r   rn   r   r   r:   r  )rH   Z
add_sprintappended_listZcurrent_sprintsZ
cur_sprintr   r   r   _calc_sprints  s*    




zCmfTask._calc_sprintsc              *      sf   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dddd d!d"d#d$d%d&d'd(d)d*g*}t   | S )+Nr    zparent.project_typezparent.auto_alarm_datezparent.logic_prefixzparent.activity.prefixz"parent.task_allow_multiple_sprintsr+   parent_task.logic_prefixr   ztags.tag_categoryzlists.plan_start_datezlists.plan_end_datelists.ordernozlists.perm_has_aclzlists.sys_typelists.logic_prefixzlists.affect_gantt_taskzmain_list.plan_start_datezmain_list.plan_end_datezmain_list.ordernozmain_list.perm_has_aclzactivity.prefixzcomments.log_levelr	  r  Zcmf_modified_byr   timetracker_historyr  r   r   r   r?   op_gantt_task.actual_start_dater   zcomponents.default_responsiblezcomponents.default_ownerz!scheme_wf.default_task_logic_typez$scheme_wf.default_subtask_logic_typezlists.default_task_logic_typezstatus.need_approverf   )r   r9   )rH   r;   r   r   r   r9     sX    -zCmfTask.save_preload_fieldsc                 O   s:   t j| d d| _| jdd t jj| df|| d S )Nr   Zapprove4Tr-   Zapprove_started)r   
CmfApproveZstart_approve_processr	  r%   CmfEventdo_eventrH   r   r   r   r   r   start_approve  s    zCmfTask.start_approvec                 C   sR   |  dddg | jjj| _| jD ]}| j| q"| jdd tj	| d d S )Nzstatus.trans_approvedzstatus.trans_approved.status_toapprovers_forTr-   Zapprove_success_full)
r8   r   Ztrans_approved	status_tory  r  r%   r   ru  rv  rH   Zapprover_forr   r   r   _approve_approved"  s    
zCmfTask._approve_approvedc                 C   sR   |  dddg | jjj| _| jD ]}| j| q"| jdd tj	| d d S )Nzstatus.trans_rejectedzstatus.trans_rejected.status_tory  Tr-   Zapprove_rejected)
r8   r   Ztrans_rejectedrz  ry  r  r%   r   ru  rv  r{  r   r   r   _approve_rejected*  s    
zCmfTask._approve_rejectedc                 C   s8   |  dddg | jjj| _| jD ]}| j| q"d S )Nzstatus.trans_updatedzstatus.trans_updated.status_tory  )r8   r   Ztrans_updatedrz  ry  r  r{  r   r   r   _approve_updated2  s    
zCmfTask._approve_updatedc                 K   sl   | d}| d}| d}tjj | |tjdd}|rL|jf d|i| | jtj tj	| d d S )Napprove_group
resolutionr   r3  )r   r  ZapproverZapprove_typeZapprove_success_one)
r   r   rt  ro   rp   Z_approve_onery  r  ru  rv  )rH   r   r  r  r   Zapprover   r   r   approve_one8  s    



 zCmfTask.approve_onec                    s   dt _t j||S )NT)ro   rq   r   create)r   r   r   r   r   r   r  D  s    zCmfTask.createz(?P<code>[A-Z\d]+-\d+)c                 C   sP   |dkrd}| j |}dd|g}|r>|dddd |D gg}tjj|||dS )	u  
        Нужно в тексте найти все потенциальные коды. Можно просто все слова...
        Какие сложности:
            - код может быть практически любым max_len = 64
            - в имени ветки нельзя пробелы
        ОСВ: код вначале, и содержит ^([A-Z0-9]+-[0-9]+).*
        NrG  r   INr"   c                 S   s   g | ]
}|j qS r   r   )r   r"   r   r   r   r   Y  s     z.CmfTask.find_related_tasks.<locals>.<listcomp>r6   r;   r   )_TASK_CODE_SEARCH_REfindallr   r	   r   )r   r   r;   Zprojectsr   ZcodesZfilter_r   r   r   find_related_tasksJ  s    	
zCmfTask.find_related_tasksc                 C   s   | j s| jjs| jjsdS | j s(| jjrz| dg g }| jD ]}|jdkr>|| q>|D ]}| j| | j| q\| j s| jjr| dg g }| jD ]}|jdkr|| q|D ]}| j| | j| qdS )u   
        При добавлении в список правильно выбирать поле lists или fix_versions
         в зависимости от типа списка
        Nzfix_versions.logic_prefixlist.releaserq  )re   fix_versionsrd   rQ   r8   r   rW   r  )rH   r  r   r   r   r   r}   \  s2    



zCmfTask._calc_fix_versionsc                 C   sl   t | j}|| j | jjr,|| jj | jjrB|| jj dd |D }ttjj	dt |id d S )Nc                 S   s   h | ]}t |jqS r   )strr   )r   r^   r   r   r   	<setcomp>  s     z4CmfTask.process_lists_count_cache.<locals>.<setcomp>Zlist_ids)r   )
r   rQ   rR  r  rd   rn   schedule_deferred_jobr   r  Zrecalculate_count_cache)rH   rQ   Zids_setr   r   r   process_lists_count_cache{  s    
z!CmfTask.process_lists_count_cachec              	      s  | j rv| jsv| jsvdt_| jjr| jr| jjjdkr| j	ddddddd	g | jj
r| jj
| jkr| j| jj
 d
| jj
j d| jj d}tj| |dd  |   |   |   |   |   |   |   |   |   | jr$| jj r$t  |   W 5 Q R X |   |    | !  | "  | #  | $  t% j|ddi|}| &  |S | jr| ' S | j(js| j r| | j(krt)ddd | jjr| *  | +  | ,  | -  | .  | jjr&| j/r&t0| jj1t0| jj2 D ]}|| j/krd | _/q| j/s| jD ]}|j3dkr4|| _/ qTq4| j/s| jD ]}|j3dkrb|| _/ qqb| jjr| j/r| 	dg | j/j3dkrt0| jj2t0| jj1 D ]}|j3dkr|| _/ qq| j/jr| j/r| j/| jkr| j| j/ | jjs&| j r:| jr:| jjjdkr:| j	ddddddd	g | jj
r| jj
| jkr| j| jj
 d
| jj
j d| jj d}tj| |dd  | jjr:| jj1r:| jj1jdkr:| jj1j
  | jj1j
}|r:|| jkr:| j4| d|j d| jj1j d}tj| |dd  | jjrtj5st0| jj2t0| jj1 D ]0}|j6dkrdt)d|j d| j ddd qdt0| jj1t0| jj2 D ]0}|j6dkrt)d|j d| j ddd q| 7  | 8  |   |   |   |   | 9  | j:jrP| j:dkrP| j3dkrPt)d| j: ddd | ;  | j<jrxtj=j>| df|| | $  t% j||}	| ?  | jr| jjs| j r| jj rt  |   W 5 Q R X | jjr| @  | jAd kr tjBC|  | j s | jr tjDE|  | jjs4| jFjr@tGtjHjI | j odtJ| jd!kpdtJ| jFd!k}
|
s| jjs| jFjs| jjr| 	d"g | K  d#D ]&}tL| |jrtGtjMjI  qʐq| j(r| j(jr| j(j3 d$krtGtjNjI | j(j1r.| j(jr.| j(j1j3 d$kr.tGtjNjI | j3jrL| j3j1d$krLd!| _O| jPjr~| jr~tQ| jjtjRr~| jS| jP | j6jr| j6dkr| TtjUjV | jWd!d% | jXr| j3d&krt)d'dd | &  | jYjs| jZjrtj[\|  |	S )(NTr   zdefault_list.plan_start_datezdefault_list.plan_end_datezdefault_list.ordernozdefault_list.perm_has_aclzdefault_list.sys_typezdefault_list.logic_prefixzdefault_list.affect_gantt_taskuU   SimpleLogic: Задача добавлена в Cписок по умолчанию "   " проекта "r  r   r   rk   FuK   Нельзя добавлять задачу в eё же подзадачиr(   rl  	list.basezmain_list.logic_prefixuS   SimpleLogic: Задача удалена из Cписка по умолчанию "r   uS   Нельзя добавить задачу в Завершенный список "z" - "uU   Нельзя удалить задачу из Завершенного списка ")r0   r   rY  rX  r   u   Вид отображения uk    временно не поддерживается, используйте "task", "list", "post", "gantt"Zspectators_changedproject.servicedeskr   r  )r   r$   r   rV   r   r   r   )rR   r]  us   DEV: Недопустимое перемещение простой задачи в структуру дерева)]re   r`   r    ro   rq   r$   rd   r@   r   r8   default_listrQ   rW   r   r   r%   rr   rt   ru   rs   rv   rw   rx   ry   rz   r   Zneed_approver   r`  ra  rx  r   r  r   r{   r|   r}   r   r~   r   r+   r:   rF  rk  r   _calc_estimate_workr   r   r   rn   r   r   r  r   r   rn  _calc_logic_type_change_guard_calc_agile_story_pointsrZ  _calc_structural_listrd  ru  rv  rb  r   parent_logic_prefixCmfSDeskSlaTriggertask_changed_hookZCmfSDeskSlaCycleZupdate_cycle_goalsr  r  r  recalculate_cacher   r  getattrr  r	   cache_child_tasks_countr   r   r   Zhook_task_tags_changedZ_clear_notifyr   r   Z_update_opened_notifiesr   rV   re  CmfTaskResAssignZsync_task_resources)rH   r   r   	audit_msginstZremoved_listr^   rm  Zold_default_listZself_instanceZis_new_with_listsrI   r   r   r   r%     s:   









$
""
(

&$
$($zCmfTask.savechangedc                 C   s  | j jsn| jjjsn| jjsn| jjjsn| jjdkr<| jjdksn| jjdkrT| jjdksn|dksn|d k	sn| j	snd S | 
dddddg | jjjpd}| jjjpd}|| }| jjj}| j j}d	}	|dk rd}g }
| j	r@t| jjD ]Z}|jd
krq|j| jjd| j j| jjj| jjjd	| jd |j| jjd dd|||d qd S | jjrLt| jjD ]n}|jd
krjqV|| jjkrV|j| jjd| j j| jjj| jjjd	| jd |j| jjd dd|||d qVt| jjD ]x}|jd
krq|| jjkr|
| |j| jjd| j j| jjj| jjjd	| jd |j| jjd dd|||d qt| jd}| j jrn| j j|d< | jjjr| jjj|d< | jjjr| jjj|d< |r
| jD ]Z}|jd
ks||
kr̐q|j| jjdf| d|kr|j| jjd dd|d d q|rf| jD ]N}|jd
ks||
kr4q|j| jj|jj||jj|jj||jjdd q|r|dkr|j| jjd |||||	| jd |j| jjd d ||||d | jjdkr"| jjdkr"| jD ]L}|jd
ks||
krq|| jjd |j| jjd dd|||d q| jjdkr| jjdkr| jD ]V}|jd
ksD||
krbqD|j| jjd||||	d  |j| jjd d!d|||d qDd S )"Nr   )startedclosedrQ   agile_story_pointsop_gantt_task.sched_durationop_gantt_task.sched_workop_gantt_task.actual_workr   r   r  rW   )estimate_spestimate_durationestimate_workestimate_countr  zscope-changed)timetracker_history_idtask_operatetask_list_operater  remaining_durationspent_durationr  r  r  r  r  Zchangez
rte-changer  )r  r  r  r  work-logged)r  r  r  r  r  Zhistory_dater  )r  r  r  r  r  r  r  closer  zstate-change)r  r  r  Zunclose)r  r  r  r  Zreopened)r  rd   r?   Zsched_durationrQ   
sched_workr   r   rn   re   r8   r@   actual_workr   Zhistory_otr_addr   Zhistory_rte_addrW   dict
time_spentremaining_estimateZend_date)rH   r  	task_listrr  r  r  r  r  r  r  Zappendedr   paramsr   r   r   r~   k  s>   



	
  

  
  

  






 


zCmfTask.calc_historyc                 C   s   | j j  | j j| _| jr(| jj   ddg}| | | jsDd S | j j| j_tjj	dd| g|d}|D ] }|j | j krj| j |_ |
  qjd S )Nr$   r?   r+   r7   r   )r$   r   r   r   r+   r8   r?   r   r	   r   r%   r   r   r   r    _change_parent_and_gantt_project  s    

z(CmfTask._change_parent_and_gantt_project)TEXKOM_db_deletec          
      O   s   |sd S d | _ | jdd ddd| gdd| gdd| gg}tjj|ddD ]}|j|d	|i| qHtjj| dd
D ]}|j|d	|i| qrtjj| dd
D ]}|j|d	|i| qtjj| ddD ]}d |_	|jdd qtj
jddd| gdd| ggddD ]}	|	j|d	|i| q d S )NTr-   r1   r0   r3   r   r+   r5   r  r/   )r   r,   r2   r4   )r?   r%   r   r^  r   rA   rB   CmfTaskCodeHistoryr	   r   rC   )
rH   r  r   r   r2  Z
gantt_taskrK   r   r0   rL   r   r   r   _delete_relations		  s     &zCmfTask._delete_relationsc                O   s   t jj| |dgdD ]}|j|d|i| qt jj| |dgdD ]}|j|d|i| qBt jj| |dD ]}|j|d|i| qld S )Nr   )r0   r,   r   r  )r   r,   )r   rE   r   rA   rF   rG   )rH   r  r   r   rO   r   r   r   _delete_history	  s    zCmfTask._delete_historyc                 O   sr   t jj| ddgdD ]}|j|| qt jj| ddgdD ]}|j|| q:t jj| ddD ]}|j|| q\d S )NTr  )r0   cmf_deletedr   )r   r  )r   rE   r   restorerF   rG   )rH   r   r   rO   r   r   r   _restore_history#	  s    zCmfTask._restore_historyc                    s   |  ddddddddd	d
g
 | jr<| jD ]}|j|| q*| j|| | j|| | j|| | j|| | j|| t j||}| j	r| j	j|| | j
s| jrttjj |   | jr| j|  |S )Nr   r"   rm   sdesk_sla_cyclesr   r+   rQ   r  rV   re  )r8   r  rA   _delete_task_resourcesr  _delete_timetracker_history_delete_subtasksr  r   r?   rQ   r  r  r   r  r  r  r+   child_task_delete)rH   r   r   Zsdesk_sla_cycleresr   r   r   rA   +	  s0        
zCmfTask.deletec                    s   t  j||}| dg | jr.| | j ntjj| d d |   | 	  | j
|| |ddr| jdkr~| jf | n| jf | |S )Nr?   )r0   Zbaseline	recursiveFr   )r   r  r8   r?   Z_restore_child_objectr   r^  r_  _restore_timetracker_historyr  _restore_task_resourcesr   r   _restore_epics_subtasks_restore_subtasks)rH   r   r   r  r   r   r   r  L	  s    	
zCmfTask.restorec                 O   s>   | dd}d|d< tjj| |d}|D ]}|j|| q(d S )Nr  Fr  ra   r,   )r   r   rD   r   rA   )rH   r   r   r  rM   rN   r   r   r   r  m	  s
    z#CmfTask._delete_timetracker_historyc                 C   s&   t jj| dd}|D ]}|  qd S )NTr  )r   rD   r   r  )rH   rM   rN   r   r   r   r  u	  s    z$CmfTask._restore_timetracker_historyc                 O   sH   | dd}tjj| |d}|D ]"}tjj|j|dr |j|| q d S )Nr  Fr   r,   )r   r,   )r   r   r	   r   r   r   rA   rH   r   r   r  
tasks_listr0   r   r   r   _delete_epics_subtasksz	  s
    zCmfTask._delete_epics_subtasksc                 O   s*   t jj| dd}|D ]}|j|| qd S )NTr  r   r	   r   r  rH   r   r   r  r0   r   r   r   r  	  s    zCmfTask._restore_epics_subtasksc                 O   s8   | dd}tjj| ||d}|D ]}|j|| q"d S )Nr  Fr*   )r   r   r	   r   rA   r  r   r   r   r  	  s    zCmfTask._delete_subtasksc                 O   s*   t jj| dd}|D ]}|j|| qd S )NT)r+   r,   r  r  r   r   r   r  	  s    zCmfTask._restore_subtasksc                 O   s.   t jjdd| gd}|D ]}|j|| qd S )Nr$   r3   r  )r   r  r   rA   rH   r   r   ZassignmentsZ
assignmentr   r   r   r  	  s    zCmfTask._delete_task_resourcesc                 O   s0   t jjdd| gdd}|D ]}|j|| qd S )Nr$   r3   Tr5   )r   r  r   r  r  r   r   r   r  	  s    zCmfTask._restore_task_resourcesc                    s   |  ddg |jdkr2tjs2| j  tjj| _| j	sJ| j
sJ| jdd | jdkrr|rr|jdkrrtjj| |d t j|d|i|S )	Nr$   r  r   Tr-   r  )commentr  )r8   r   ro   r   Zcmf_modified_atr]   rp   r   Zcmf_modified_by_idre   Zis_recursion_saver%   r  r   r  r  r   _comment_save_hook)rH   r  r   r   r   r   r   r  	  s    

zCmfTask._comment_save_hookc           
         s   |sg }|sdg}|sg }|dddgddddggd	d
ddgd
dd ggg}|oT| d}| dd }	|r||sn|	s||dd|gg}|d
 |d t j|f||||d|S )Nr`   r   r  r   r   r  rl  r  r1   r   Ztrashr3   ra   searchr7   r$   object_fieldsr6   r;   r   r   rW   r   field_options_list
r   relation_field_namer  r6   r;   r   Zfilter_by_projectr   ra   r  r   r   r   lists_options_list	  s6    

   zCmfTask.lists_options_listc           
         s   |sg }|sdg}|sg }|dddgg}|o4| d}| dd }	|r\|sN|	s\|dd|gg}|d |d	 t j|f||||d
|S )Nr`   r   r3   r  ra   r  r7   r   r$   r  r  r  r   r   r   releases_options_list	  s.    

   zCmfTask.releases_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   r7   r1   r   rl  r  r  )r   r  r   r  r  r6   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   r7   r  r1   r   r   r   r  )r   r   r  r  r   r   r   parent_task_options_list	  s    z CmfTask.parent_task_options_listc              	   K   s   |sg }|ddddgddd ggg}|rF| dd rF|dd| dgg}| dd }|r|dddd	| d	gd
dd	| d	gddd	| d	ggg}tjjf |||d|S )Nr1   Z
cmf_hiddenr7   Fra   r  r`   r"  r0  r   r#  r  )r   r   ZCmfComponentr   )r   r  r  r6   r;   r   r   r  r   r   r   components_options_list	  s     4zCmfTask.components_options_listc                    s   |dkr$| j |f||||d|S |dkrH| j|f||||d|S |dkrl| j|f||||d|S |dkr| j|f||||d|S |dkr| j|f||||d|S t j|f||||d|S )NrQ   r  )r  Zaffected_versionsr   r+   r   )r  r  r  r  r  r   r  r  r   r   r   r  
  s<         zCmfTask.field_options_listT)
system_jobc              	   K   sR  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|}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   )r   r;   r   zAuto task reopenu'   Переоткрываем задачу)r$   r   NZdefault_projectr   zNew auto task for r   z
) project 
rG  )r   r`   r   rV   rm   rR   r$   r   )printhashlibZmd5encodeZ	hexdigestr   r	   r   r   r
  r  r   rX   r]   r   r%   r1  r=   r;   r   Zget_obj_by_tuuid_strr`   r   r   r@   )r`   r   Z
extra_textrR   responsible_idZcmf_owner_idra   _kwargsZtask_keyZ	task_hashZ	task_coder0   rV   rm   r$   r   r   r   	auto_task#
  sD    


  
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/  r3   Tr  r   r  r  )Zin_progressr   )
r   r1  r   r   r  r	   r   r   r   r@   )r   r6   r   r   ZpersonsZin_progress_filterZcount_filterr3  resultZin_progress_countr   r   r   r   get_responsibles_tasks_countP
  s    

z$CmfTask.get_responsibles_tasks_countc                 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   rd   r$   r   r
  r   rQ   rU   r   Z	scheme_wfZcalc_workflowr   r   r   r   ry   `
  s$    	zCmfTask._calc_workflowc                 C   s\   | j jsd S | jdkr6| jjr6| jjdkr6tddd | jjdkrX| jdkrXtddd d S )Nr   ua   Нельзя изменить Логический тип задачи на Гант-проектTr(   uT   Нельзя изменить Логический тип у Гант-проекта)rU   rd   r   rn   r:   r   r   r   r   r  s
  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+   rd   rU   r   rn   _calc_cache_branch_gantt_path_recalc_gantt_pathr   r   r   r   rt   
  s    
zCmfTask._calc_gantt_pathr   c              	   C   s  |dkrt ddd |r|ddddg | j|jkr>|j| _| j|jkrR|j| _| j|jkrf|j| _|jd	kr~|| _d | _n|jd
kr|| _tjj| dddddddgdD ]}d}|j| jkr| j|_d}| jd
kr| |_| j|_d}nR| jd	kr| |_d |_d}n4|j| jkr"| j|_d}|j| jkr<| j|_d}|j	rd|
|  |jj|jjkrdd}|rv|jdd |j	r|jd |d d qd S )Nd   uM   DEV: Защита от рекурсии: _recalc_gantt_path: if r_count > 100Tr(   r   r   r   r   r   r   cache_branch_gantt_pathr+   r  )r+   r;   Fr-   r   )r+   r_count)r:   r8   r   r   r   r   r   r	   r   r  r  r  r   rn   r%   r  )rH   r+   r  ZchZ	need_saver   r   r   r  
  s\    

  

zCmfTask._recalc_gantt_pathc                 C   s   | j   | js$| j dkr$d | _d S |s<| ddg | j}|sJg | _d S |jj}|d krftddd ||jj|j	j|j
j|j jdf| _| jjdd	 | jD krtd
| j
 d| jj
 ddd d S )Nr]  z#parent_task.cache_branch_gantt_pathro  zODEV: WARNING: _calc_cache_branch_gantt_path: if cache_branch_gantt_path is NoneTr(   )r   r   r`   r   c                 S   s   g | ]}|d  qS r  r   )r   tr   r   r   r   
  s     z9CmfTask._calc_cache_branch_gantt_path.<locals>.<listcomp>ul   Произошло зацикливание! Попытка добавить дочернюю задачу "uK   ", которая уже является родительской для "r  )r   r   r  r  r8   r+   r@   r:   r   r   r`   )rH   r+   r  r   r   r   r  
  s.    
z%CmfTask._calc_cache_branch_gantt_pathc                 C   sP   |  dg tjjdd| jgdd|jggd}|sLd| _|   | jdd	 d
S )u   
        Убирает метку дерева у родительской задачи при удалении или перемещении дочерних задач
        r  r+   r7   r   r  r  FTr-   N)r8   r   r	   r   r   r  r  r%   )rH   r   Zhave_childrenr   r   r   r  
  s    "zCmfTask.child_task_deletec                 C   sp   | j jsdS | j jrH| dg | j jsHd| j _| j   | j jdd | j jrl| j | j jksl| j j|  dS )u   
            Рассчет has_child_tasks
            должен вызываться после _calc_parent_task
        Nzparent_task.has_child_tasksTr-   )	r+   rd   r   r8   r  r  r%   rn   r  r   r   r   r   rs   
  s    
z)CmfTask._calc_parent_task_has_child_tasksc                 C   s  | j jsd S d }| ddg | j r| j jr| j jjr| j jj}| j jj}|r|ddddddg | j| d	|j d
}t	j
| |dd  nt|jr| j|kr|j| jkr|jddddddg | j|j d|jj d|j d}t	j
| |dd  | j jr| j j}|ddg |jr|jjr|jj}|jj}|r||kr| j| d|j d}t	j
| |dd  n\|jr| j|kr|j| jkr| j|j d|jj d|j d}t	j
| |dd  d S )Nr   z0responsible.primary_role.structural_project_listr   r   ZordernoZperm_has_aclr   r   uU   SimpleLogic: Задача добавлена в структурный список "uG   " т.к. он указан в должности исполнителяr   r   u>   SimpleLogic: Задача добавлена в список "r  u   " т.к. он является Структурным проектом Главной роли ответственного по задачеz,primary_role.structural_project.default_listz$primary_role.structural_project_listuS   SimpleLogic: Задача убрана из структурного списка "uX   " т.к. он указан в должности прошлого исполнителяu<   SimpleLogic: Задача удалена из списка "u   " т.к. он является Структурным проектом Главной роли прошлого ответственного по задаче)rV   rd   r8   r   r   Zstructural_project_listrQ   rW   r`   r   r   r%   r  r$   rn   r  )rH   Zappend_structural_project_listr   r  Zold_responsibleZremove_structural_project_listr   r   r   r  
  s^    


zCmfTask._calc_structural_listc                 C   sl   | j s| jjs| jjd ksd S | jrht| jjtjrh| dg | jjd krh| jj	jd k	rh| jj	| _d S d S )Nz!parent.default_agile_story_points)
re   r$   rd   r  r@   r   r   r   r8   Zdefault_agile_story_pointsr   r   r   r   r  /  s    
z CmfTask._calc_agile_story_pointsc                 C   s   | j jsd S | jr8| jj  | j | jjkr8tddd | jddg | jjr`| jj| j jkr|| jj	s|| j | j_| j
  d S )Nu   DEV: FATAL: нельзя изменять поле estimate_work, когда существует базовый Гант-планTr(   r  
const_work)r  rd   Zbp_gantt_taskr  r   r:   r?   r8   rn   r  r%   r   r   r   r   r  9  s    
zCmfTask._calc_estimate_workc                 C   s   |  dg | jf |}tj }| jd |d |_| jjrV|jpHd| jjj	 |_d|j
_|  |jdd tj|d| j d| j dd	  |jj	S )
u    Создание задачи из шаблона
        :param self: Шаблон документа
        :param params: Параметры для шаблона
        :return: Идентификатор новой задачи
        tmplt_document.textr   z%d.%m.%YrG  Tr-   u0   Задача создана из шаблона r   r   )r8   create_from_templaterY   rZ   r`   strftimetmplt_documentr   r   r@   r$   rd   r{   r%   r   r   r   r   )rH   r  new_taskZnow_dater   r   r   create_task_from_templateK  s    
$z!CmfTask.create_task_from_templatec                    s&   | j dgd | jdkrdS t  S )uB    Шаблон уведомлений для разных workflow r   r   ztask.ticketzhelpdesk_mail_notification.html)r8   r   r   +get_default_mail_notification_template_namer   r   r   r   r  j  s    
z3CmfTask.get_default_mail_notification_template_namec                    sp   |  | j tj| jjpd|d< | jr4| jjjp6d|d< |d  dd	dd | j
D  7  < t jf |S )NrG  Zobj_result_textZobj_responsible_namesr   c                 S   s   g | ]}t |jpd qS )rG  )r  r`   )r   rr   r   r   r   v  s     z-CmfTask.full_search_index.<locals>.<listcomp>)r8   Zfull_search_fieldsr   ZCmfFullSearchZ
strip_htmlresult_textr@   rV   r`   rU  re  r   full_search_indexrH   r   r   r   r   r  q  s
    &zCmfTask.full_search_index   Добавленоc                 C   s*   t jj| |||||d}| jd|d |S )N)Z
start_daterm   r  )rr  )r   r   Ztimetracker_task_change_timer~   )rH   r  r  r   daterm   rr  r   r   r   timetracker_change_timez  s    
  zCmfTask.timetracker_change_timer8  )	only_oncer  rR   c                 K   s   t j|  d S r   )r   r	   _recalculate_codes)r   r  r   r   r   recalculate_codes_celery  s    z CmfTask.recalculate_codes_celeryc                 C   st   d}d}t jjdd| gddg||| gdd}||7 }|s>d S |D ]$}|jsNqB|jdd |jdd	 qBt  qd S )
Nr      r"   r7   r   T)r6   r;   slicer,   )from_recalculater-   )r   r	   r   r"   
_calc_coder%   Zcommit_with_event)r   r   limitZ
task_slicer0   r   r   r   r    s"    
zCmfTask._recalculate_codesc              	      sP  t  < tjj| d}|s4td W 5 Q R  dS td|  tjj|dgd}tdt|  dd	  t	| fd
dd}d}|D ]}|d7 }td|  |rtj
j|dD ]}|  q|jjdd  d| }tj
jdd|gddr.td| d |d7 }|jjdd  d| }q||_|jdd qW 5 Q R X dS )u  
            Метод для ручного запуска.
            Пересчитает номера в кодах задач начиная с единицы.
            ! Прошлые коды задач не сохраняются
            ! Пошлые коды задач удаляются
            Если код занят задачей из другого проекта - он пропусается
        r  u   Проект не найден!NuY   Удаляем историю выдачи кодов задачам из проекта r   )r"   r;   u   Всего задач: c                 S   s   z
t | W S    Y dS X d S )Nr   )r   )r   r   r   r   tryint  s    
z:CmfTask.reindex_project_tasks_code_numbers.<locals>.tryintc                    s    | j jdd S )Nr   r   )r   r@   
rpartition)r  r  r   r   rI    rJ  z<CmfTask.reindex_project_tasks_code_numbers.<locals>.<lambda>rK  r   r   u'   Обрабатываем задачу: )r0   r   r7   Tr5   u   Код u    занятr-   )r`  Zdisable_notifyr   r   r   r  r	   r   r   rT  r  rA   r   r@   r  r   r%   )r   Zwith_history_deleter"   r  r   r0   ZhistZnew_coder   r  r   "reindex_project_tasks_code_numbers  s0    	
z*CmfTask.reindex_project_tasks_code_numbers<   )r  Zsoft_time_limitr  rR   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| |d dkrt  qtd| d| d |S )u   Актуализация кеша кол-ва задач в епике (нужно ли для подпроекта? Вроде как нет).r   r   r  )r   r;   r   r+   r7   r  zUpdate cache_members_count z -> r   Tr-   )Znode_idZelements_countztree-node-count-changes-ztree-node-count-changesr  zRecalculate r  z lists caches)r   r	   r   r   r  ro   r   r   r%   r@   Zcmf_emit_eventZ
cmf_commit)r  r   Ztotal_countZ
calc_countZcmf_epicZ
real_countZ
event_datar   r   r   r    s$    
 
zCmfTask.recalculate_cache	recursion)returnc             	      sX   t  }| dddddddg | jr<|| jj|d d	}t j|d
|i||S )Nzfollowers.personzfollowers.person.cmf_deletedzfollowers.person.does_not_workzfollowers.notify_volumezfollowers.follow_childrenr   r+   r   r  r  )r   r8   r+   unionget_all_followersr   )rH   r  r   r   r  r   r   r   r    s    
   zCmfTask.get_all_followersinline_save)tmp_objcreate_formui_form_moder;   c                   s~   | j |ddddddddd	g	d
d|}|jrZ|jjdkrZd}t j|||||d|S |pb|j}t j||||d|S )NrU   r   zproject.ui_form_schemezproject.cust_field_conf_schemezproject.logic_prefixr  r    request_type,request_type.ui_form_view_inner.ui_form_jsonT)r;   r,   r  r  )r  r  r  r;   )r  r  r;   )r   r"   r   r   ui_getr    )r   r  r  r  r;   r   r   r   r   r   r    s"       
zCmfTask.ui_getc                    s   t t|j}|p|j}|rn|jdkrn|r2|}n| j|jddgd}|jrn|jj	rnt
 j|||||jj	dS t
 j|||||dS )Nr  r  r  r  )r  tmp_is_public_formtmp_ui_view_formr  ui_form)r   Zget_cache_projectr  r   r    r   r   r   r  Zui_form_view_innerr   _build_ui_form)r   r  r  r  r  r  Ztmp_projectr   r   r   r   r     s"    

 
 zCmfTask._build_ui_formc                 C   s   t jjddgddS )u   
        Экран по умолчанию если нет никаких правил и схем экранов

        Returns:
            CmfUiForm: системный экран по умолчанию
        zui_form.task:defaultZui_form_jsonT)r   r;   cache_inmemory)r   Z	CmfUiFormr   r   r   r   r   _get_default_ui_form  s    zCmfTask._get_default_ui_form)copy_attachmentscopy_relationscopy_subtaskscopy_all)r`   r#  r$  r%  r&  c                   s  |rd}d}d}|  dddddddd	d
dg
 t j|||d|}|jjdd|_tjjddd}	|rdd|	gg}
tj	j
|
dd| gg dgdD ]}| }||_|  qtj	j
|
dd| gg dgdD ]}| }||_|  q| jstj	| ||	d  | | d|_|S )NT**zattachments.urlr   rQ   re  rd  zattachments.url_previewzattachments.url_preview_imgr  r
  )r`   r#  r   r  zsystem.clone)r   r!  relation_typer  r2   r3   r   r4   )r2   r4   r(  )r8   r   rQ  r
  r  r   r   ZCmfRelationTyper   rC   r   cloner2   r%   r4   Zis_template_clone_op_gantt_taskre   )rH   r`   r#  r$  r%  r&  r   r   new_objZ
clone_typer2  ZrelationZnew_relationr   r   r   rQ    s@       




zCmfTask.copyc                 C   sv   |j dg |j  |_ d|j _d|j _d|j _d|j _d |j _d |j _t	d|j _
t	d|j _||j _|  d S )Nr'  r   z0.00)r?   r8   r)  r  Zactual_durationZactual_completeZactual_myself_workZactual_start_dateZactual_finish_dater   Zactual_costZactual_myself_costr0   r%   )rH   r+  r   r   r   r*  <  s    zCmfTask._clone_op_gantt_taskc                    s2   |  dg | jdkr*d| j d| j S t jS )Nr   r   z	/project/r  )r8   r   r[  r   r   hrefr   r   r   r   r,  J  s    
zCmfTask.hrefc           	      K   sz   t t}d}d}| j|dddg|| |d | gd}|D ]"}|jD ]}||j  d7  < qDq:t||k rlqv|d7 }q|S )Nr   i  z--r   zlists.idr   )r6   r;   r  )r   r   r   rQ   r   r   )	r   r6   r  r  ZpageZ	page_sizer  r0   Zlist_r   r   r   count_tasks_by_listsR  s      

zCmfTask.count_tasks_by_listsc                 C   s|   | j s| jS | dddg | jddg | jr>| jj  | jrr| jjrr| jrr| jjrr| jjj	d | jjj	 S | jjj	S )Nzproject.task_code_prefix'project.task_code_use_logic_type_prefixzlogic_type.obj_code_prefixtask_code_use_logic_type_prefixtask_code_prefixr   )
r   Zcode_prefixr8   r"   rU   Zobj_code_prefixr   r/  r0  r@   r   r   r   r   get_code_prefixb  s    zCmfTask.get_code_prefixc              
      s   t   }dd l}| }d}d}tjjdd|gddr|d7 }t   }||k sjtd| d	| j d
| | }|dkr"td|dd| j d| j	 dd| j
ko| j d	 q"|S )Nr   i'  r   r7   Tr5   r   u8   Превышен лимит поиска кода limit=z model=uA   , возможно надо отключить def gen_code: passz$!!! --- gen_code::duration too long z.1fz sec, r   z, r   )r   gen_codetimer   r  r   AssertionErrorr   r  r   r;   r   )rH   r   r3  startr  r   Zdurationr   r   r   r2  ~  s    

 .zCmfTask.gen_codec                    s  | j r| jjs| jjs|sd S | j s2t   d S | j rH| j drHd S d }d }| jr\| j}| jjrt| jjrt| jj}|r|  }| j j	| dr| j j	
d|
dkr| j j	}|rtjj|dstj|| |d}|  d| j_t   d S | jjrj| j j	|   dsj| j j	}| jsV|rVtjj|dsVtj|| |d}|  d | _ t   d S | jjr| dg | jr| jjr| j j	|   ds| j j	}| js|rtjj|dstj|| |d}| jjr||_|  t   d S )NzA-r   )r   )r   r0   r"   Tr.  )r   r"   rd   rU   r   r
  r   rn   r1  r@   r   r   r  r   r%   re   r8   r/  r   )rH   r	  r"   Zproject_oldZ
new_prefixZ	prev_codeZcode_historyr   r   r   r
    sn    
,
$


zCmfTask._calc_coder;   r6   c             	   O   sh   |sg }|sg }| j |||d|}g }|D ]4}z|  || W q. tk
r`   Y q.Y q.X q.|S )Nr6  )r   Z_acl_check_readrW   ZCmfPermissionError)r   r;   r6   r   r   Zres_uncheckedr  r  r   r   r   public_list  s    zCmfTask.public_listc                    s   d|d< d|d< t  jf |S )NFZwith_parent_ownerZinherit_executors)r   all_relation_personsr   r   r   r   r8    s    zCmfTask.all_relation_personsc                 C   s<   | j j  | j jj}| | jj|  | | jj| d S r   )r?   r  r   r@   #_update_actual_work_for_all_parentsr+   rn   r   )rH   actual_work_timer   r   r   _update_actual_work  s    
zCmfTask._update_actual_workc                 C   sT   |sd S |j   |j j  |j  j|7  _|j jdk rBd|j _|j jdd d S )Nr   F)Z
user_input)r?   r   r  r%   )rH   r0   r:  r   r   r   r9    s    
z+CmfTask._update_actual_work_for_all_parentsz@hourly)r  r  Zschedulec                  C   s  t d ddddgdddggdd	d
ggddd gddtjjtjjdgg} tjj| dddddddddddddgdD ]^}|j	r|
 }t d|  |jjr|jj|_|jjdd|_|j  |j|_d |_d |_|  |  |jd
d qtt d|  |jdkr|jjdkrP|jj}|  |jr|j|jkr||_q|jjrd|jj|_|jr~|jjdd|_|jjdd|_|  qt|jjd krt|jjdd|_|jjdk r|j  |  qtd S )!Nz(Run CmfPerson.cron_celery_check_periodicr1   zstatus.coder  r   r   r  period_create_newr7   Tperiod_intervalperiod_next_datez<=rT   rp  r   r
  period_clear_checkboxr   r  rS   rX   r   z6CmfPerson.cron_celery_check_periodic: create new task )r   r-   z2CmfPerson.cron_celery_check_periodic: reopen task )r   r   r   ztox-checklist--checkedrG  pause)ro   r   rY   rZ   r[   r\   r   r	   r   r<  r  r  r   r   r
  r  r   rX   r]   rS   r=  r>  r%   Z_cacl_next_periodr   r  r@   r?  rC  r   )r2  r0   r  Zold_deadliner   r   r   cron_celery_check_periodic  sf    
      






z"CmfTask.cron_celery_check_periodicc                    sJ   |    |   |   |   |   |   |   t j|| d S r   )	r   rr   rs   rt   ru   rb  r  r   _save_importrw  r   r   r   rB  T  s    zCmfTask._save_importc                    s*   t  |}|s&|tjdddg7 }|S )Nr(  r4   r2   )r   import_shop_fieldsr   rC   )r   Zfields_namer  r   r   r   rC  ^  s    zCmfTask.import_shop_fieldscsvc              '      s   |s|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dddd d!d"d#d$d%d&d'g'}t jj D ]}|d(rb|| qbt |||S ))Nr   r   r`   r   r  zcmf_author.namezcmf_author.loginzcmf_owner.namezcmf_owner.loginzparent.namezworkflow.namezlogic_type.namezstatus.namer   zcompany.namezresponsible.namezresponsible.loginzexecutors.namezexecutors.loginzspectators.namezspectators.loginz	tags.namezattachments.namezactivity.namez
lists.namezgit_repos.namezgit_branches.namezgit_merge_requests.namezgit_commits.namezrequest_type.namers  z op_gantt_task.actual_finish_datezop_gantt_task.actual_durationr  zop_gantt_task.sched_start_datezop_gantt_task.sched_finish_dater  zop_gantt_task.perform_workr  Zcf_)r   r	   r;   keysr   rW   r   export2file)r   r;   ZbqlZformat_filerI   r   r   r   rF  e  sN                         
zCmfTask.export2file)NN)F)F)F)F)F)NNN)r  NN)N)NNNNN)NNNNN)NNNN)NNNN)NNNN)NNNN)NNNNNN)N)r   )N)r  NN)F)FNFN)N)F)N)NNrD  )__name__
__module____qualname__classmethodr   r   r   r&   rP   r_   ri   r   r   r   r   r   r   rv   r   r   r   r   rr   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r(  r*  r4  rB  r?  rE  r   rF  r|   r\  ru   rb  rf  rj  rk  rn  r9   rx  r|  r}  r~  r  r  recompileASCIIr  r  r}   r  r%   r~   r  r  r  r  rA   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  staticmethodZcmf_deferred_jobr  r  ry   r  rt   r  r  r  rs   r  r  r  r  r  r  r  r  r  r  r  r   r  r  r   r"  r  boolrQ  r*  propertyr,  r-  r1  r2  r
  r7  r8  r;  r9  rA  rB  rC  rF  __classcell__r   r   r   r   r	      s  
, 1
%$*A0
	A2  G 
+%%*J9	t0 c !!                                               +.9
	
,
	&!KK
r	   )rY   r3  collectionsr   r   decimalr   r  Zredis.exceptionsr   Zwerkzeug.datastructuresr   Zdateutil.relativedeltar   Zcmf.includeZcmf.fields.base_fieldsr   Zmodules.task.fields.cmf_taskmodulesZ#modules.servicedesk.models.cmf_taskZservicedeskr   Zcmf_taskZCmfTaskMixinr0   r;   r	   r   r   r   r   <module>   s   