
    ho                        d dl Zd dlmZ d dlmZmZmZ d dlm	Z	m
Z
 d dlmZmZmZ d dlZd dlT d dlT d dlmZ  G d d	e          ZdS )
    N)tzutc)ROUND_UP
ROUND_DOWNROUND_HALF_UP)defaultdict
namedtuple)	bindparamfuncand_)*)CmfGanttTaskc                   J    e Zd ZdZej        ddgz   Zed             Zedd            Zd Z	d Z
d	 Zg dd
fdZ fdZed             Zed             Zed             Zed             Zed             ZddZddZd Zd Zd ZddZd ZddZddZddZd Zd ZddZ d Z!d  Z"d! Z#d" Z$d# Z%d$ Z&d% Z'd& Z(e) e*dd'gd()          d*                         Z+dd+Z,dd,Z-d- Z.d. Z/d/ Z0	 	 	 dd0Z1d1 Z2dd2Z3d3 Z4d4 Z5dd5Z6d6 Z7	 	 dd7Z8d8 Z9d9 Z:d: Z;d; Z<d< Z=d= Z>d> Z?d? Z@d@ ZAddAZBddBZCdC ZDdD ZEdE ZFddFZGe) e*dGdddHgd(I          ddJ                        ZHddKZIddLZJdM ZKdN ZLddOZMdP ZNdQ ZOdR ZPdS ZQdT ZRdU ZSdV ZTdW ZUdX ZVdY ZWdZ ZXd[ ZYd\ ZZd] Z[dd^Z\d_ Z]d` Z^da Z_ddcZ`dddZaddeZbdd
d
df fdg
Zc fdhZdd
d
di fdj
Ze fdkZf fdlZg fdmZhddoZidp Zjdq Zkdr Zlds ZmddtZndu Zoeddv            Zpe) e*dwd(x          dy                         Zqe) e*dzd(x          dd{                        Zre)d|             Zse) e*dd}gd(dd~          d                         Zte) e*dd(x          dd                        Zue)dd            Zve)d             Zw xZxS )r   Toutline_insert_aftercalc_critical_pathc                 p   t                                           }g d}t           j                            d ||          }|r|D ]}||         ||<   ||_        |                                 t
                                          5  |                    ddd           d d d            n# 1 swxY w Y   |S )N)sched_start_datesched_finish_datesched_duration
sched_cost
sched_workconstrain_start_typeconstrain_start_dateconstrain_finish_typeconstrain_finish_dateprojectgantt_projecttaskparent_taskactual_start_dateactual_finish_date)parentr   fieldsFT)emitnotify	only_data)modelsr   getr!   fix_null_variablescmfutildisable_notifysave)clsr   baseline
gantt_taskr"   op_gantt_taskfields          (./modules/gantt/models/cmf_gantt_task.py_create_gantt_task_for_baselinez,CmfGanttTask._create_gantt_task_for_baseline   s   ((**
T T T +//t$v/VV 	9 9 9$1%$8
5!!$
%%'''##%% 	F 	FOOuOEEE	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	Fs   B++B/2B/Nc                    t                                           }|r|                     ||          S |j                                         |j        |_        ||_        |j        |_        |j        |_        |                                 |	                                 |j
        |_
        t                                          5  |                    dd           d d d            n# 1 swxY w Y   |S )NF)r#   r$   )r&   r   r2   r   loadr   	cmf_owner
cmf_author
_calc_type_calc_projectr   r)   r*   r+   )r,   r   r-   r.   s       r1   create_gantt_taskzCmfGanttTask.create_gantt_task&   s%   ((**
 	G66tXFFF 	!!!#'#5
 
  $~
 $
 	  """!%!1
##%% 	6 	6OOuO555	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6s   C''C+.C+c                     | j         rb| j         j        rV| j         j        j        }|dk    rd| _        |dk    rd| _        |dk    rd| _        |dk    rd| _        |d	k    r	d
| _        d S d S d| _        d S )Nignore4-ignoreconst_duration0-const_durationconst_resource2-const_resource
const_work1-const_workconst_duration_and_work3-const_duration_and_work)r   r   default_gantt_task_typetask_sched_type)selfdefault_types     r1   r7   zCmfGanttTask._calc_typeC   s    9 	6* 	69,DLx'''1$///'9$///'9$|++'5$888'B$$$ 98 $6D       c                 V    | j         r| j         j        r| j         j        | _        d S d S d S N)r   r   rG   s    r1   r8   zCmfGanttTask._calc_projectS   s<    9 	-* 	-9,DLLL	- 	- 	- 	-rI   c                 R    | j         r| j         j        S | j        r| j        j        S d S rK   )r   r/   r   rL   s    r1   _get_parent_gantt_taskz#CmfGanttTask._get_parent_gantt_taskX   s:     	2#11 	4%33	4 	4rI   Fc                 .   ||                                  }| j        j        dk    r;t          j                            g ddd| j        gdd| j        gg|gz   |          }n7t          j                            dd| j        gdd| j        gg|gz   |          }|rzt          j                            g dd	d| j        ggd
g          }|rJd |D             }t          j                            dd|gg|gz   |          }|	                    |           |S )Ntask.gantt_projectr   ==Nr   rR   r!   filterr"   r   relation_type.coderR   system.additional_parentin_linkzout_link.op_gantt_task_idc                 &    g | ]}|j         j        S  )out_linkop_gantt_task_id.0rels     r1   
<listcomp>z:CmfGanttTask._get_children_gantt_tasks.<locals>.<listcomp>y   s    ,w,w,wsS\-J,w,w,wrI   idIN)
save_preload_fieldsr   logic_prefixr&   r   listr!   CmfRelationOptionslistextend)rG   
add_filterr"   include_additionalchild_gantt_tasks additional_child_tasks_relationsadditional_gantt_task_idsadditional_gantt_taskss           r1   _get_children_gantt_tasksz&CmfGanttTask._get_children_gantt_tasks^   s   >--//F9!%999 & 3 8 8///$dDI6tT[1  L	!
  !9 ! ! !' 3 8 8"D$)4tT[1  L!  !9 ! !  	A/5/G/M/M  WO  WO  WO  R[  ]a  cg  cl  Qm  VnToSp 0N 0r 0r,/ A,w,wVv,w,w,w))/)<)A)A4QUWpJqIr  wA  vB  JB  KQ)A  *R  *R&!(()?@@@  rI   c                 R    g d}t                                                      |z   S )N)r   r!   r   r   zgantt_project.op_gantt_taskr   zparent_task.gantt_projectparent_task.op_gantt_taskz(parent_task.op_gantt_task.outline_numbertask.logic_prefixztask.parent_task.logic_prefixtask.has_child_tasksztask.plan_start_dateztask.plan_end_dateztask.responsibleztask.executorstask.parent_task task.gantt_project.op_gantt_task)superrc   )rG   r"   	__class__s     r1   rc   z CmfGanttTask.save_preload_fields   s1    
 
 
( ww**,,V33rI   c                     | j         j        rd S | j         | j        z  dz  }t          |                              t          d          t
                    S )Nd   z1.11rounding)r   is_null_perform_completeDecimalquantizer   rG   ress     r1   _perform_costzCmfGanttTask._perform_cost   sM    ?" 	4o 66<s||$$WV__x$HHHrI   c                     | j         j        rd S | j         | j        z  dz  }t          |                              t          d          t
                    }t          |          S Nry   1rz   )r   r|   r}   r~   r   r   intr   s     r1   _perform_durationzCmfGanttTask._perform_duration   sY    & 	4!D$::S@cll##GCLL8#DD3xxrI   c                     | j         j        rd S | j         | j        z  dz  }t          |                              t          d          t
                    }t          |          S r   )r   r|   r}   r~   r   r   r   r   s     r1   _perform_workzCmfGanttTask._perform_work   sW    ?" 	4o 66<cll##GCLL8#DD3xxrI   c                    | j         j        s| j        j        rdS |                                 }t	          j        t	          j        t          |j        pd                              }t          j        	                    |          }| j         |k    rdS |
                    | j         j        | j        j                  }t          |          dk    r)|
                    | j         j        |          }||z  dz  }nd}|dk    rd}t          |                              t          d          t                    }t          |          S )Nr   secondsry   r   rz   )r   r|   r   _get_calendardttimezone	timedeltar   datetimenowget_work_timedeltavaluer~   r   r   )rG   calendartzr   delta_finish_time_secdelta_now_time_secperform_completer   s           r1   r}   zCmfGanttTask._perform_complete   s;    ( 	)1	1%%''[c(2C2Hq.I.IJJJKKkoob!!  C''1 ( ; ;D<Q<WY]YoYu v v$%%**!)!<!<T=R=XZ]!^!^14IICO  #c!!"&''00
0SS3xxrI   c                     | j         j        rdS | j         j        dk    r;g ddd| j         gdd| j        gg}t          j                            |          }|rdS dS )	NTrP   rQ   r   rR   r!   rT   F)r   has_child_tasksrd   r!   r&   r   sget)rG   _filterhas_childrens      r1   r   zCmfGanttTask.has_child_tasks   s~     9$ 	49!%999 ,++ $	24-G
 ".3373CCL turI   c                    |sd S d}|}| j         dk    r| j        rd}d}nq| j        rjd}| j        j        }| j        dk    r||k    rd}|}d|d}n7| j        dk    r||k    rd}|}d	|d}n| j        d
k    r||k     r
d}|}d|d}d| d|d}|r3|s1d| j        j         d| j        j         d| d}t          |d           |S )NF0-constTu   невозможно изменить дату начала, если зафиксированы дата окончания и длительность (   Фиксированное начало %d.%m.%Y3-after   Начало не раньше 4-before   Начало не позже    ограничение "uE   " конфликтует с плановой датой начала <   Конфликт планирования: В задаче "" () .abort)	r   r=   r   r   r   r   namecode	cmf_alertrG   estimated_datereturn_correct_datealertcorrect_datetext
constraintconstrain_dates           r1   check_correct_start_datez%CmfGanttTask.check_correct_start_date   sv    	F%%22t7J2E nDD& 	_J!6<N(I55.N:Z:Z-aaaa

*i77N^<[<[-X~XXX

*j88^n=\=\-V^VVV
^z ^ ^DR]^ ^D  	(, 	(~RVR[R`~~eienes~~w{~~~Dd$''''rI   c                    |sd S d}|}| j         dk    r| j        rd}d}nq| j        rjd}| j        j        }| j        dk    r||k    rd}|}d|d}n7| j        dk    r||k    rd}|}d	|d}n| j        d
k    r||k     r
d}|}d|d}d| d|d}|r3|s1d| j        j         d| j        j         d| d}t          |d           |S )NFr   Tu   невозможно изменить дату окончания, если зафиксированы дата начала и длительностьr   .   Фиксированное окончание r   1-after%   Окончание не раньше 2-before#   Окончание не позже r   uK   " конфликтует с плановой датой окончания r   r   r   r   r   )	r   r=   r   r   r   r   r   r   r   r   s           r1   check_correct_finish_datez&CmfGanttTask.check_correct_finish_date  sv    	F%$	11d6I1E nDD' 	eJ!7=N)Y66>^;[;[-gnggg

+y88^n=\=\-^^^^^

+z99n~>]>]-\>\\\
dz d dJXcd dD  	(, 	(~RVR[R`~~eienes~~w{~~~Dd$''''rI   c                    d\  }}}|                                  rc| j        j        dk    rS|                                  }|                    |                                            |                                \  }}}|}| j        dv r | j        }|r|rt          ||          }n|p|}|}| j	        dv r | j
        }|r|rt          ||          }n|p|}d}| j        r| j        }n|}|||fS )u  
        Получает из родительской задачи ограничения
        по дате начала, дате окончания и максимальной длительности.

        Returns:
            start_limit: Defaults to None
                левая граница, за которую нельзя уйти влево (_plan_start_limit_min)
            finish_limit: Defaults to None
                правая граница, за которую нельзя уйти вправо (_plan_finish_limit_max)
            duration_limit: Defaults to None
                лимит длительности, нельзя превысить (_plan_duration_limit_max)
        NNNrP   r   r   r   r   N)rN   r   rd   load_fieldsrc   get_parent_plan_limitr   r   maxr   r   minr=   r   )rG   parent_start_limitparent_finish_limitparent_duration_limitparent_gantt_taskstart_limitfinish_limitduration_limits           r1   r   z"CmfGanttTask.get_parent_plan_limit.  sI    JZF/1F&&(( 	wTY-CG[-[-[ $ ; ; = =))$*B*B*D*DEEEM^MtMtMvMvJ 35J($(>>>3K @1 @!+/ABB)?-?*%)@@@5L C 3 C"<1DEE+B/B 	3!0NN2NL.88rI   c                 `   dx}x}}| j         sdS |                                 D ]}|j        dv r0|s|j        j        }n!|j        rt          ||j        j                  }|j        dv r|sm|j        j        }|j        rY|j        rRt          j
                            |                                |j        j        t          |j                             }|}n|j        rt          ||j        j                  }|j        r`t          j
                            |                                |j        j        t          |j                             }t          ||          }|j        dv r0|s|j        j        }n!|j        rt          ||j        j                  }|j        dv r|sl|j        j        }|j        rX|j        rQt          j
                            |                                |j        j        t          |j                            }|}n|j        rt          ||j        j                  }|j        r_t          j
                            |                                |j        j        t          |j                            }t          ||          }|j        r&|s|j        }n|j        rt          ||j                  }|j         r^|                                \  }}}	|s|}n|rt          ||          }|s|}n|rt          ||          }|s|	}|	rt          ||	          }|||fS )u~  
        !!! Очень тяжелый метод

        Получает из дочерних задач ограничения
        по дате начала, дате окончания и максимальной длительности.

        Returns:
            start_limit: Defaults to None
                левая граница, за которую нельзя уйти вправо (_plan_start_limit_max)
            finish_limit: Defaults to None
                правая граница, за которую нельзя уйти влево (_plan_finish_limit_min)
            duration_limit: Defaults to None
                самая большая фикс. длительность или фикс. трудозатраты (пока нет поддержки ресурсов),
                нельзя меньше (_plan_duration_limit_min)
        Nr   )r   r   r   )r   r   r   )r   ro   r   r   r   r   r   r   r   r&   CmfCalendarget_date_by_durationr   r   r   r=   get_childrens_plan_limit)
rG   r   r   r   r.   r   r   ch_start_limitch_finish_limitch_duration_limits
             r1   r   z%CmfGanttTask.get_childrens_plan_limitY  s     7;::l^# 	$##88:: H	L H	LJ.2III" Z","A"GKK4 Z"%k:3R3X"Y"YK/3JJJ" M","B"HK!0 ;Z5U ;/5/A/V/V&4466&<B !:;;;0 0,
 ';5 M"%k:3S3Y"Z"ZK!0 M/5/A/V/V&4466&<B !:;;;0 0,
 '*+7K&L&L/3III# ]#-#C#ILL5 ]#&|Z5U5[#\#\L.2HHH# P#-#B#HL!0 =Z5T =060B0W0W&4466&;A
 9::1 1-
 (=4 P#&|Z5T5Z#[#[L!0 P060B0W0W&4466&;A
 9::1 1-
 (+<9N'O'O( T% T%/%>NN. T%(9R%S%SN) LEOEhEhEjEjB1B" C"0KK# C"%k>"B"BK# F#2LL$ F#&|_#E#EL% L%6NN& L%(9J%K%KNL.88rI   c                     t          | dd          rd S d| _        |                                 \  | _        | _        | _        |                                 \  | _        | _        | _	        d S )N_calc_plan_limits_cache_doneFT)
getattrr   r   _plan_start_limit_min_plan_finish_limit_max_plan_duration_limit_maxr   _plan_start_limit_max_plan_finish_limit_min_plan_duration_limit_minrL   s    r1   _calc_plan_limits_cachez$CmfGanttTask._calc_plan_limits_cache  st    47?? 	F,0)&&(( 	_"D$?A^ ))++ 	_"D$?A^A^A^rI   c                 f   | j         rd| j        r]t          j                            |                                 | j         j        | j        j        | j        j        p|          }|| _        n| j         j	        r| j        j	        rd| _        | j        j
        r|                     d||           d S d S )N)r   from_dtto_dtforce_include_endsr   T)from_calc_sched_durationfrom_child_changesfrom_sched_dates_changed)r   r   r&   r   get_duration_minutesr   r   	is_manualr   old
is_changed_do_sched_duration_is_changed)rG   r   r   r   calendar_durations        r1   _calc_sched_durationz!CmfGanttTask._calc_sched_duration  s        
	$T%; 
	$ & 2 G G++---3,2#'>#7#M;M	 !H ! ! #4D"& 	$4+A+E 	$"#D) 	b..BTH` / b b b b b	b 	brI   c                    | j         rU| j        rNt          j                            |                                 | j         j        | j        j                  | _        d S | j         j        r| j        j        rd| _        d S d S d S Nr   )	r   r    r&   r   r   r   r   actual_durationr   rL   s    r1   _calc_actual_durationz"CmfGanttTask._calc_actual_duration  s    ! 	%d&= 	%#)#5#J#J""$$d&<&BDD[Da$c $cD   #' 	%D,C,G 	%#$D   	% 	% 	% 	%rI   c                    t           j                            |                                 | j        j        t          | j                             }|                     ||          }| j	        dk    r| j
        r| j
        |k    r| j
        }|S )u  
        Расчитывает дату начала.
        При возникновении конфликтов ограничений, откатывает на дату ограничения при rollback=True

        Args:
            rollback (bool, optional): Defaults to False
                при конфликте откатить на дату ограничения

        Returns:
            sched_start_date:
                плановая дата начала
        r   r   r   )r&   r   r   r   r   r   r   r   r   r   r   )rG   rollbackr   r   s       r1   _calc_sched_start_datez#CmfGanttTask._calc_sched_start_date  s      +@@  $"8">TEXAYAY@Y[ [  88MU 9 W W &)33. 4373MP`3`3`#9rI   c                     t           j                            |                                 | j        j        t          | j                            }|                     ||          }|S )u  
        Расчитывает дату окончания.
        При возникновении конфликтов ограничений, откатывает на дату ограничения при rollback=True

        Args:
            rollback (bool, optional): Defaults to False
                при конфликте откатить на дату ограничения

        Returns:
            sched_finish_date:
                плановая дата окончания
        r   )	r&   r   r   r   r   r   r   r   r   )rG   r   r   r   s       r1   _calc_sched_finish_datez$CmfGanttTask._calc_sched_finish_date  sn      +@@  $"7"=s4CV?W?WY Y !::.OW ; Y Y ! rI   c                    | j         j        s| j         dk    r	d | _        d S | j        j        r| j        j        rd S | j        r.| j        s'|                     |          | _        |rd | _        nd S | j        rF| j        s?|                                 | _        | j        dk    r|                                 | _        d S | j        dk    r#| j        dk    r| j        rt          d           d S d S d S d S )Nr   r   r   r   u   Плановый период может не соответствовать плановой длительности, т.к. все переменные зафиксированы)
r   r|   r   r   r   r   r   r   r=   r   )rG   r   s     r1   _calc_sched_periodzCmfGanttTask._calc_sched_period  sD   & 	$*=*B*B%)D"F ( 	T-C-K 	F  	)? 	%)%A%A8%A%T%TD" (,%% ! 	$*? 	$($?$?$A$AD!)Y66)-)E)E)G)G&F $	11d6PT]6]6]bfbu6]  N  O  O  O  O  O 216]6]6]6]rI   c                    | j         j        s| j         dk    r	d | _        d S | j        j        r| j        j        rd S | j        rVt          j                            |                                 | j        j        t          | j                             | _        d S | j        rWt          j                            |                                 | j        j        t          | j                              | _        d S d S r   )
r   r|   r    r   r&   r   r   r   r   r   rL   s    r1   _calc_actual_periodz CmfGanttTask._calc_actual_period?  s    ' 	4+?1+D+D&*D#F!) 	d.E.M 	F! 	&,&8&M&M""$$d&<&BCH\D]D]'_ '_D#F " 	%+%7%L%L""$$d&=&Cc$J^F_F_E_&a &aD"F	 	rI   c                 ~   | j         dk    r| j        j        r| j        j        ru| j        dk    rlt	          j        | j        | j        z  dz            }t          |d          }| j        j        s|| j        k    r#|| _        | 	                                 dS dS dS dS dS | j         dk    r| j        j        r| j
        j        rw| j
        dk    rnt	          j        | j        | j
        z  dz            }t          |d          }| j        j        s|| j        k    r%|| _        | 	                                 dS dS dS dS dS dS )uR   
        Вычисляет фактический % завершения
        0-workr   ry   5-timetrackerN)actual_complete_typeactual_workis_not_nullr   mathfloorr   actual_completer|   $notify_parent_update_actual_completetimetracker_sched_work)rG   tmp_completes     r1   _calc_actual_completez"CmfGanttTask._calc_actual_completeS  s    $00+ @0K @PTP_cdPdPd#z$*:T_*Ls*RSS"<55'/ @<$BV3V3V+7D(==?????@ @ @ @PdPd 4W3V &/99+ @0K0W @\`\w{|\|\|#z$*:T=X*X[^*^__"<55'/ @<$BV3V3V+7D(==????? :9@ @ @ @\|\| 4W3VrI   c                     | j         sdS | j        dk    rdS | j        dk    rdS | j        dk    rm|                     dg          }|sdS t          |          }d}|D ]7}|r"|j        |j        k    r||j        j        pdz  }&||j        j        pdz  }8||z  }nN| j        dk    r(| j        j        d	k    r0t          j
                            g d
dd| j        ggddg          }n+t          j
                            dd| j        gddg          }|sdS d}d}	|D ]}|rs|j        |j        j        k    r^|j                            ddg           ||j        j        j        pdz  }|j        j        j        dk    r|	|j        j        j        pdz  }	w||j        j        pdz  }|j        j        dk    r|	|j        j        pdz  }	|	|z  dz  }n| j        dk    rdS | j        dk    rdS | j        |k     r	|| _        dS dS )uB   
        updated_ch_gantt_task - указан, когда
        Nr  r  
1-completer  )r"   r   2-story_pointsrP   rQ   r   rR   agile_story_pointszstatus.status_typerS   r   =CLOSEDry   3-costz4-fixed)r   r  ro   lenra   r  r   r   rd   r&   CmfTaskre   r   r  statusstatus_type)
rG   updated_ch_gantt_taskch_gantt_task_listtotal_countsum_actual_completecres_actual_completech_task_listtotal_story_pointsfinished_story_pointss
             r1   _calc_summarry_actual_completez+CmfGanttTask._calc_summarry_actual_completeh  s    # 	F$00F$77F&,66!%!?!?HYGZ!?![![% 011K"#' H H( HQT5J5M-M-M'+@+P+V+[Z[['''1+<+B+GaG''"5"C&*::: y%)===%~22333($	: 12FG  3  I  I  &~22=#ty:Y;OQe:f  3  h  h  "#$%!! 	Q 	Q( QQT5J5O5R-R-R).::<PRf;ghhh&*?*D*W*]*babb&,18DPP-1F1K1^1d1ihii-&!*>*D*II&x+x77-1E1K1PqP-"7:L"Ls"R&(22F&)33F"555#6D    65rI   c                    |                                   | j        dv r| j        s| j        r| j        | _        nd | _        | j        dk    r| j        | _        n| j        dk    rL| j        }| j        r!| j        rt          | j        | j                  }|r| j        r| j        |k     r|| _        n| j        dk    rL| j        }| j        r!| j        rt          | j        | j                  }|r| j        r| j        |k    r|| _        n>| j        dk    rt          j	        
                    dd| j        gg d	          }d }d }|D ]n}|j        j        j        j        }|r>|j        r7|j        j        j        }t          j                            |||j                  }|r|rt          ||          n|}od }|                                 }|r|j                                        }	|	r|	}n| j        r| j        }|r|rt          ||          | _        n4|s|r	|p|| _        n&| j        r| j        | _        | j        r| j        | _        | j        r(| j        r!| j        | j        k    rt/          d
d           | j        r(| j        r!| j        | j        k     rt/          dd           | j        dk    | _        | j        r | j        j        r|                                  |                     d           d S )N)r   r   r   r   r   r   1-earlyrX   rR   )z(out_link.op_gantt_task.sched_finish_dateconstrain_lagz"out_link.project.calendar.timezonerS   u~   Нельзя указать Дату начала больше зафиксированной у дочерней задачиTr   u   Нельзя указать Дату начала меньше зафиксированной у родительской задачиr%   )r   r   r   r   r   r   r   r   r&   rf   re   r   r[   r/   r   r   r$  r   r   r   r   rN   r4   r   lock_sched_start_dater   _do_sched_start_date_is_changedr+   )
rG   r   in_relationsmax_prev_dater   in_relationfinish_datenew_sched_start_dater   parent_sched_start_dates
             r1   #_do_constrain_start_date_is_changedz0CmfGanttTask._do_constrain_start_date_is_changed  s   $$&&&$(JJJ, B1F B,0,A)(,D%$	11$($=D!!&)33#8( ^T-G ^#&t'@$B\#]#]  9)> 9$BWZjBjBj(8%&*44#8( ^T-G ^#&t'@$B\#]#]  9)> 9$BWZjBjBj(8%&)33!388!43zzz 9  L !MH+ f f)2@RX |;#< |*3;DH"("4"I"I(T_alaz"{"{K fGT$eC{$C$C$CZeM#'  $ ; ; = =  B*;*L*Q*Q*S*S'* C+B(+ B'+'A$ N!5 N(+M;O(P(P%% N"6 N(5(M9M%) C(,(B%) C(,(B%% 	d$*? 	dDDY\`\vDvDv  W  _c  d  d  d  d% 	l$*? 	lDDY\`\vDvDv  _  gk  l  l  l  l0 &*%>)%K"  	3T%:%E 	300222		D	!!!!!rI   c                     g }| j         j        dk    rd S |                                 rP|                                 }|                    |                                            |                    |           dd| j         gg dg}t          j                            |dg          }|rcd |D             }dd| j	        gd	d
|gg}t          j
                            ||                                           }|                    |           |S )NrP   r[   r  )rV   r  rW   rX   rS   c                 0    g | ]}|j         j        j        S rZ   )rX   r   ra   r]   s     r1   r`   z8CmfGanttTask._get_parent_gantt_tasks.<locals>.<listcomp>  s     +i+i+iSCK,=,@+i+i+irI   r!   task_idrb   )r   rd   rN   r   rc   appendr&   rf   re   r!   r   rh   )rG   parent_gantt_tasksr   r   additional_parents_relationsadditional_parents_tasks_idsadditional_parents_filteradditional_parentss           r1   _get_parent_gantt_tasksz$CmfGanttTask._get_parent_gantt_tasks  sL   9!%999F&&(( 	9 $ ; ; = =))$*B*B*D*DEEE%%&7888 di(CCC
 (.'?'D'DGMVK (E (Y (Y$' 	:+i+iLh+i+i+i(3,D">?)% "(!4!9!9AZAEAYAYA[A[ ": "] "]%%&8999!!rI   c                     d }|                      ddg           | j        r| j        j        }|p!t          j                            ddg          S Nzproject.calendarproject.calendar.timezonezsystem:defaultr   )r   r"   )r   r   r   r&   r   r'   )rG   r   s     r1   r   zCmfGanttTask._get_calendar(  s\    ,.IJKKK< 	-|,H]6-117GQ[P\1]]]rI   c                    d }d }g d}|                      |d          }|D ]I}|j        | j        k    r|                                 |                    | j        j        d          |_        d |_        |j        r|	                                 n|
                    d           |                                 |                                 |                    d           |s|j        j        }nt          ||j        j                  }|j        r)|s|j        j        }nt!          ||j        j                  }|                     |           |                     |           K| j        r+| j        r$| j        rd | _        | 
                                 d S |r|| _        |r|| _        |                     d           d S )	N)r   !=TTri   rj   r   r   r%  r   r   )ro   r   r   r   r   r   newr   r   "_calc_sched_period_for_child_tasksr   _alert_changed_plan_fields_check_start_finish_relationsr+   r   r   r   r   r   r   r   )rG   r   r   ri   child_tasks
child_tasks         r1   rB  z/CmfGanttTask._calc_sched_period_for_child_tasks1  s!    ...
44
_c4dd% #	M #	MJ%2222444.8.Q.Q#'#8#<(, /R / /
+ 04
,- AAACCCC1141@@@5577788:::$///# \#-#>#D  #&'79T9Z#[#[ + c( c(2(D(J%%(+,=z?[?a(b(b%))9I)JJJ**:K*LLLL> 		?d1 		?d6K 		?%)D"##%%%%% 9(8%  ;):&%%%>>>>>rI   c           	      6   |                      | j        j                   |                                  | j        rx| j        j        rl| j        rO| j        | j        k     r?| j        | _        t          d| j        j         d| j        j	         d| j        dd           | 
                                 d S d }| j        r.| j        r'| j        s d | _        |                     d           d	}n|                     d
           d}|                     |           d S )Nr?  u/   Предупреждение: В задаче "r   u2   ) дата начала перемещена на r   ub   , так как была позже даты ограничения дочерней задачи.Tr   
start_dater   durationchanged_field)r   r   rA  r   r   r   r   r   r   r   rB  r   lock_sched_finish_dater   r   r   _calc_resourcesrG   rL  s     r1   r'  z,CmfGanttTask._do_sched_start_date_is_changedh  sj   %%T5J5N%OOO$$&&& 	>D$9$= 	>) @d.H4K`.`.`(,(B% DIN  _c_h_m  NRNht   @ @ @ 3355555 M" +t'< +TE` +)-&'''666 ,))4)HHH *  } =====rI   c                    |                      | j        j                   |                                  d }| j        rL| j        sE|                                  d}| j        r'| j        j        r| j        r| 	                                 n| 
                    d           d}| j        s|                     |           d S d S )Nr?  rH  TrI  rJ  rK  )r   r   rA  r   r   r   r   r   r   rB  r   rN  rO  s     r1    _do_sched_finish_date_is_changedz-CmfGanttTask._do_sched_finish_date_is_changed  s    &&d6L6P&QQQ$$&&& 	't'< 	'##%%%(M# :(=(H :TMb :77999%%t%DDD&M# 	>  } =====	> 	>rI   c                    |                      | j        j                   |                     | j        j                   |                     d           | j        r|                                  |                     d           d S )Nr?  TrI  rJ  rK  )	r   r   rA  r   r   r   r   rB  rN  rL   s    r1   _do_sched_dates_is_changedz'CmfGanttTask._do_sched_dates_is_changed  s    %%T5J5N%OOO&&d6L6P&QQQ!!4!@@@ 	633555:66666rI   c                 (   |j         r| j         r|j         | j         k     s|j        rh| j        rc|j        | j        k    rUd}t          |                    |j        j        |j        j        | j        j        | j        j                             d S d S d S d S )Nu   Задача "{}" ({}) вышла за диапазон плановых дат родительской задачи "{}" ({}))r   r   r   formatr   r   r   )rG   rF  msgs      r1   %_alert_child_task_outside_sched_datesz2CmfGanttTask._alert_child_task_outside_sched_dates  s    (	n-1-B	n/$2GGG, H151G H043III TCcjj!5z7KTY^]a]f]kllmmmmm HGGGIIrI   r1     )	only_onceonly_once_argspriorityc                 F   t           j                            |           }|sd S |                                }|                    |           t           j                            ||          }|sd}|                    d||           |                    d           d S )Nra   ra   r"   T)deferredrF  ignore_child_taskr%  )r&   r   r'   rc   r   from_sched_dates_of_child_tasksr+   )r1  child_task_idr`  r   r"   rF  s         r1   #from_sched_dates_of_child_tasks_jobz0CmfGanttTask.from_sched_dates_of_child_tasks_job  s     "&&'&22 	F))++   (,,f,MM
 	% $,,dzev,www		D	!!!!!rI   c                 r   |s@| j         j        dk    r0t          | j        | j        j        |j        j        |d           dS | j        r|r|s|                     |           dS |t                      }| j        j        |v rt          dd           |
                    | j        j                   d}d}|s|nd}|s|nd}dg d	g d
g}	|                     |	d          }
|
D ]e}|r|j        |j        k    r|j        r!|s|}n|j        s|}n|j        |j        k    r|}|j        r!|s|}I|j        s|}S|j        |j        k     r|}f|r|j        }|r|j        }|s"|r |j        r|j        s|j        |k     r|j        }|s"|r |j        r|j        s|j        |k    r|j        }d}d}| j        ru|rsd|j         j         d|j         j         d}| j        j        }| j        dk    r||k    rd|d}n2| j        dk    r||k     rd|d}n| j        dk    r||k    rd|d}nd}d}| j        ru|rsd|j         j         d|j         j         d}| j        j        }| j        dk    r||k    rd|d}n2| j        dk    r||k     rd|d}n| j        dk    r||k    rd|d}nd}|r6|p|}t          d| j         j         d| j         j         d| d| d	d           || _        || _        | j        j        s| j        j        r|                     dd           |s4|r2| j        |j        k     r"|j        | _        |                     d            |                                  |                                 }|rt4                                          5  |D ]k}|                    |                                            |                    | |!           |                                 |                     d"d#           l	 ddd           n# 1 swxY w Y   |!                    | j        j                   dS )$u  
        Обновляет плановые даты родительской задачи.
        Плановая дата начала = самая ранняя плановая дата начала всех подзадач
        Плановая дата окончания = самая поздняя плановая дата окончания всех подзадач

        Args:
            child_task (optional): Defaults to None
                измененная дочерняя задача, которая еще не сохранена.
            ignore_child_task (bool, optional): Defaults to False
                игнорировать дочернюю задачу при обновлении дат родительской задачи.
        rP   )r1  rb  r`  kwargsNu   Невозможно обновить даты из-за обнаруженного цикла обновления дат задач связями Дополнительный родитель/Дополнительная дочерняя задача.Tr   OR)r   r=  N)r   r=  Nr>  "r   )r   r   r   r   r   r   r   r   r   r   r   r   uU   Конфликт планирования: В родительской задаче "u   ) ограничение "u<   " конфликтует с дочерней задачей r   )r   r   r@  )pathF
user_inputr%   )"r   rd   schedule_deferred_jobrc  ra   r   r   rW  setr   addro   r   r   r   r   r   r   r   r   r   r   r   r   rD  r8  r)   disable_aclr   rc   ra  rC  r+   remove)rG   rF  r`  rj  r_  min_start_datemax_finish_dateschild_task_with_min_startchild_task_with_max_finishri   gantt_tasksr.   r   conflict_child_task_min_startr   conflict_child_task_max_finishr   conflict_child_taskr3  r   s                       r1   ra  z,CmfGanttTask.from_sched_dates_of_child_tasks  s     		DI26JJJ!8#w}%/]%8):     F> 	  G"3 G:::FFFF<55D7=D   B JNO O O O6G$QJJT!7H%RZZd" ,,,---


 44
_c4dd% 	@ 	@J jmz}<<* ?0 ?0:--4E ?4>112CjFaaa4>1+ @1 @1;..5G @5?223E
Hddd5?2$ 	H6GN% 	L9K! 	:n 	:0	:9C9T	:0>AA'9N! 	;&6 	;/	;8B8T	;/2BBB):
(,%$ 	5 	5.Y1J1O1T .Y .Y2K2P2U.Y .Y .Y)#'#<#B )Y66&*>>>gH\ggg

+y88&)===^?S^^^

+z99&)===\=Q\\\

04-)-&% 	6*: 	6/[2L2Q2V /[ /[3M3R3W/[ /[ /[*$($>$D!*i77(,AAAnNcnnn

,	99(+@@@eEZeee

,
::(+@@@cCXccc

15. 	x"?"aCa k9>k k.2ink kXbk kTgk k krvx x x x !/!1 + 	Xt/E/P 	X%%RV%WWW ! 	HZ 	HD4G*Jc4c4c",";D..$.GGG**,,, "99;; 		M$$&& M M); M M%%11$2J2J2L2LMMM%EE! F    &@@BBB%**et*LLLLMM M M M M M M M M M M M M M M 	DGM"""""s   A/PPPc                    |                                  }|rt                                          5  t                      }|                    | j        j                   |D ]S}|j        j        |vrC|                    | ||           |                                 |	                    dd           T	 ddd           dS # 1 swxY w Y   dS dS )uq  
        Обновление дат начала и окончания родительской задачи и доп родительских задач.
        Передает дочернюю задачу (self), так как она еще не сохранена
        и родительская задача не может получить обновленные данные.

        Args:
            ignore_child_task (bool, optional): Defaults to False
                игнорировать дочернюю задачу при обновлении дат родительской задачи.
        )r`  rj  FTrk  N)
r8  r)   rp  rn  ro  ra   r   ra  rC  r+   )rG   r`  r3  rj  r.   s        r1   update_parent_task_sched_datesz+CmfGanttTask.update_parent_task_sched_datesS  sM    "99;; 	J$$&& J Juu'''"4 J JJ!}*$66"BB .?!% C   
 #==???"5DIIIJJ J J J J J J J J J J J J J J J J J	J 	Js   BCC	Cc                    |                                  }|D ]}|j        dk    rt          d           | |         r||         r| |         ||         k     r|j        dk    r,||         r$| |         ||         k    rt          d            d S |j        dk    r,||         r$| |         ||         k     rt          d            d S | |         ||<   |                                 |                    |           d S )Nr   ^   Дата родительской задачи является зафиксированнойr   u   Предупреждение: Плановая дата начала дочерней задачи больше плановой даты начала родительской задачиr   u   Предупреждение: Плановая дата начала дочерней задачи меньше плановой даты начала родительской задачи)
date_field)r8  r   r   r+   _change_parent_start_date)rG   r~  parentsr   s       r1   r  z&CmfGanttTask._change_parent_start_datem  sa   ..00!( 	S 	S 5BBz{{{J S)::)F S$zJZ]noy]zJzJz$9ZGGL]^hLiGZ(+<Z+HHH  ]  ^  ^  ^FF$9YFFK\]gKhFZ(+<Z+HHH  ]  ^  ^  ^FF04Z0@!*-!&&(((!;;z;RRR%	S 	SrI   c                 F   |                                  }|D ]}|j        dk    rt          d           | |         r||         r| |         ||         k    r|j        dk    r,||         r$| |         ||         k     rt          d            d S | |         }|j        dk    rB||         r:| |         ||         k    r(t          d           |j        r||j        k    r|j        }|||<   |                                 |                    |           | j        dk    | _        d S )Nr   r}  r   u   Предупреждение: Плановая дата окончания дочерней задачи меньше плановой даты окончания родительской задачиr   u   Предупреждение: Плановая дата окончания дочерней задачи больше плановой даты окончания родительской задачи)r8  r   r   r   r+   _change_parent_finish_dater   r&  )rG   r~  r  r   
date_values        r1   r  z'CmfGanttTask._change_parent_finish_date  s   ..00!( 	I 	I 6)CCz{{{J I)::)F I$zJZ]noy]zJzJz$:iGGL]^hLiGZ(+<Z+HHH  i  j  j  jFF!*-
$:jHHM^_iMjHZ(+<Z+HHH  i  j  j  j(> M:PaPwCwCw%6%L
0:!*-!&&(((!<<ZHHH%)%>)%K"""rI   c                 <   |                                   | j        dv r| j        s| j        r| j        | _        nd | _        | j        dk    r| j        | _        n| j        dk    r9| j        }| j        r!| j        rt          | j        | j                  }|r|| _        n|| j        dk    rK| j        }| j        r!| j        rt          | j        | j                  }|r| j        r| j        |k    r|| _        n&| j        r| j        | _        | j	        r| j	        | _        | j        rP| j
        r!| j        | j
        k    rt          dd           | j        r!| j        | j        k     rt          dd           | j        dk    | _        | j        r@| j        j        r4| j        r| j        dk    r| j        sd | _        |                                  | j        r9| j        j        r-| j        dk    r| j        sd | _        |                                  |                     d	           d S )
N)r   r   r   r   r   r   u   Нельзя указать Дату окончания больше зафиксированной у родительской задачиTr   u   Нельзя указать Дату окончания меньше зафиксированной у дочерней задачиr%  )r   r   r   r   r   r   r   r   r   r   r   r   rM  r   r   r   r   rQ  r'  r+   )rG   r   s     r1   $_do_constrain_finish_date_is_changedz1CmfGanttTask._do_constrain_finish_date_is_changed  s   $$&&&%)KKK- D$2H D-1-C*)-D&%22%)%?D""'944 $ :) ad.I a$'(BDD_$`$`!  ;):&':55 $ :) ad.I a$'(BDD_$`$`!  ;$*@ ;DDZ]nDnDn):&) C(,(B%) C(,(B%! 	n* vt/EHc/c/c  i  qu  v  v  v  v* nt/EHc/c/c  a  im  n  n  n  n0 '+&@I&M#! 	4d&<&G 	4" -D,E,R,RW[Wp,R(,%11333  	3T%:%E 	3.);;@Z;)-&00222		D	!!!!!rI   c                    | j         dk    rH| j        dk    r=| j        j        s1| j        j        s%|rt          dd           nt          dd           | j        r,t          d| j        j         d| j        j	         dd           |sB|s$| j
        rd | _        |                     d	           |s|s|                     d
           d S d S d S d S )Nr   u  Конфликт планирования: невозможно изменить трудозатраты, если установлена опция "Фиксированные Ресурсы" и зафиксированы даты начала и окончания.Tr   u   Конфликт планирования: невозможно изменить длительность, если зафиксированы даты начала и окончания.ua   Невозможно изменить плановую длительность, у задачи  (uZ   ) установлена опция "Фиксированная длительность".r   rJ  rK  )r   r   r   r   r   r   r=   r   r   r   r   r   r   rN  )rG   from_sched_work_changedr   r   r   from_calc_resourcess         r1   r   z*CmfGanttTask._do_sched_duration_is_changed  s    %22t7QU^7^7^1< 8_EIE_Ej 8_& {  $& & & & &  nuy{ { { {  	 rz~  {D  {I r r  MQ  MV  M[ r r ry}   $ # 	?+ 7( 2-1D*'''666  , ?4K ?$$:$>>>>>+	? 	?(? ? ? ?rI   c                 .    |                                   d S rK   )r   rL   s    r1   _do_actual_duration_is_changedz+CmfGanttTask._do_actual_duration_is_changed  s      """""rI   c                    t                               d| j        j         d| j        j        j                    | j        j        rd S | j        dk     r6t          d| j        j	        j         d| j        j        j         dd           | j
        }|r|sd}|s| j        j        d	k    r| j        | _        |                                  | j        j        pd| j        j        pdz
  }t                               d
| j        j         d| j        j        j         d| j        j        pd d| j        j        pd d| j        j         
           |                                 r| j        j        d	k    rt"                                          5  |                                 }|                    |                                            |                    |           |                    d           |                    d           d d d            n# 1 swxY w Y   |s3| j        j        r)t2          j                            | j        |           d S d S d S )Nz*_do_actual_work_is_changed start, gt_id : 
, t_code: r   u@   "Фактические трудозатраты" задачи "r   u   ) стали ниже нуля.Tr   rP   z"_do_actual_work_is_changed gt_id: z, gt.actual_work.new: z, gt.actual_work.old: z, work_delta: from_add_childr%  )gdebugra   r   r   r   r  r|   r   r   r   rd   actual_myself_workr  rA  r   rN   r)   rp  r   rc   from_child_add_work_do_actual_work_is_changedr+   r   r&   CmfTimeTracker"_op_gantt_actual_work_changed_hook)rG   from_timetrackerr  r   
work_deltar   s         r1   r  z'CmfGanttTask._do_actual_work_is_changed  s   	lTW]llVZV_VdVjllmmm# 	Fa  hY]YbYgYm  h  hrvr{  sA  sG  h  h  h  pt  u  u  u  u. 	#/ 	#"O 	749#9=Q#Q#Q&*&6D#""$$$&*/aD4D4H4MAN
	 ZTW] Z ZdinNb Z Z'+'7';'@qZ ZX\XhXlXqpqZ Z BF  BR  BXZ Z 	[ 	[ 	[ &&(( 	7TY-CG[-[-[$$&& 7 7$($?$?$A$A!!--d.F.F.H.HIII!55jAAA!<<D<QQQ!&&&6667 7 7 7 7 7 7 7 7 7 7 7 7 7 7   	\D$;$F 	\!DDTYPZ[[[[[	\ 	\ 	\ 	\s   A=HHHc                 $   | j         j        rd S | j         dk     rt          dd           | j        dk    r}| j        j        rq| j        dk    rft          j        | j         | j        z  dz            }t          |d          }| j	        j        s|| j	        k    r|| _	        | 
                                 |                                 r| j        j        dk    r| j         j        pd| j         j        pdz
  }t                                           5  |                                 }|                    |                                            |                    |           |                    d	           d d d            d S # 1 swxY w Y   d S d S d S )
Nr   ue   "Фактические Затраты" стал ниже нуля, выставляем в ноль.Tr   r  ry   rP   Frl  )actual_costr|   r   r  r   r  r  r  r   r  r	  rN   r   rd   rA  r   r)   rp  r   rc   from_child_add_costr+   )rG   r  
cost_deltar   s       r1   _do_actual_cost_is_changedz'CmfGanttTask._do_actual_cost_is_changed@  s   # 	Fa}  FJ  K  K  K  K$00* @t!/C/C#z$*:T_*Ls*RSS"<55'/ @<$BV3V3V+7D(==???&&(( 	9TY-CG[-[-[*.3!8H8L8QPQRJ$$&& 9 9$($?$?$A$A!!--d.F.F.H.HIII!55jAAA!&&%&888	9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9	9 	9-[-[s   A'FFFc                 V    | j         j        rd S | j        dk    rd S | j        dk    rd S d S )Nr  r  )r  r|   r  rL   s    r1   _do_actual_complete_is_changedz+CmfGanttTask._do_actual_complete_is_changedX  sE    ' 	F$00F &(22F 32rI   c                     | j         j        pd| j         j        pdz
  }| j        s| j         | _        n| xj        |z  c_        |                     |           d S )Nr   r  )r  rA  r   r   r  r  )rG   r  r  s      r1   !_do_actual_myself_work_is_changedz.CmfGanttTask._do_actual_myself_work_is_changedh  sp    -16Q4;R;V;[Z[\
# 	+  $6D
*''9I'JJJJJrI   c                     | j         j        pd| j         j        pdz
  }| j        s| j         | _        n| xj        |z  c_        |                                  d S r   )actual_myself_costrA  r   r   r  r  rG   r  s     r1   !_do_actual_myself_cost_is_changedz.CmfGanttTask._do_actual_myself_cost_is_changedr  sj    -16Q4;R;V;[Z[\
# 	+  $6D
*'')))))rI   c                    | j         j        rd S | j        | j         k    r | j         | _        |                                  | j        r| j         | j        k     rq| j        dz   d| j        dz   d}| j         dz   d| j         dz   d}| j        rt          d| d| dd           n!| j        | _         |st          d	| d
           |                                  | 	                                r| j
        j        dk    r| j         j        pd| j         j        pdz
  }t                                          5  | 	                                }|                    |                                            |                    |           |                                 |                    dd           d d d            n# 1 swxY w Y   |s|s|s|                     d           d S d S d S d S )N<      ч    мu   Нельзя запланировать меньше Трудозатрат, чем запланировано в подзадачах ( < ub   ). Увеличьте Трудозатраты или уменьшите их у подзадач.Tr   u   Указано Трудозатрат меньше, чем запланировано в подзадачах. Выставили uo   . Если нужно уменьшить Трудозатраты, уменьшите их у подзадач.rP   r   Frk  workrK  )r   r|   r
  %_do_timetracker_sched_work_is_changedr   agregat_workrA   r   r  rN   r   rd   rA  r   r)   rp  r   rc   from_child_agregate_workrC  r+   rN  )	rG   from_sched_duration_changedr   r   r  r  r   r  r   s	            r1   _do_sched_work_is_changedz&CmfGanttTask._do_sched_work_is_changed|  s   ?" 	F&$/99*./D'66888 	U !222"&"3r"9XXd>ORT>TXXX $2 5RR$/B:NRRR
? 	U A#-A A2>A A A IMN N N N N '+&7DO- U! #T9E#T #T #T U U U* 	""$$$&&(( 	ITY-CG[-[-[/-2t7J7OaPJ$$&& I I$($?$?$A$A!!--d.F.F.H.HIII!:::FFF!<<>>>!&&%4&HHHI I I I I I I I I I I I I I I ( 	70K 	7Tg 	7  v 66666	7 	7 	7 	7 	7 	7s   5A<F==GGc                    | j         j        rd S | j         | j        k     rN| j        r#t	          d| j          d| j         dd           n$| j        | _         t	          d| j         d           |                                 r| j        j        dk    r| j         j        pd	| j         j	        pd	z
  }t                                          5  |                                 }|                    |                                            |                    |           |                                 |                    d
d           d d d            d S # 1 swxY w Y   d S d S d S )Nu   Нельзя запланировать меньше Расходов, чем запланировано в подзадачах (r  uX   ). Увеличьте Расходы или уменьшите их у подзадач.Tr   u|   Указано Расходов меньше, чем запланировано в подзадачах. Выставили ue   . Если нужно уменьшить Расходы, уменьшите их у подзадач.rP   r   Frk  )r   r|   agregat_cost
const_costr   rN   r   rd   rA  r   r)   rp  r   rc   from_child_agregate_costrC  r+   rG   r  r   s      r1   _do_sched_cost_is_changedz&CmfGanttTask._do_sched_cost_is_changed  s   ?" 	F ?T... C s#s s373Ds s sz~@ @ @ @ @ #'"3 B  Z^  Zk B B B C C C&&(( 	ITY-CG[-[-[/-2t7J7OaPJ$$&& I I$($?$?$A$A!!--d.F.F.H.HIII!:::FFF!<<>>>!&&%4&HHHI I I I I I I I I I I I I I I I I I	I 	I-[-[s   A<EEEc                 v    | j         r| j        r|                                  d S |                                  d S rK   )r   r   r   r   rL   s    r1    _do_actual_start_date_is_changedz-CmfGanttTask._do_actual_start_date_is_changed  sG    ! 	)d&: 	)$$&&&&&&&(((((rI   c                     | j         s$| j        r| j        r|                                  d S |                                  d S rK   )r   r    r   r   r   rL   s    r1   !_do_actual_finish_date_is_changedz.CmfGanttTask._do_actual_finish_date_is_changed  sQ    % 	)$*A 	)dFZ 	)$$&&&&&&&(((((rI   c                    | j         dk    r|                                  nd| j         dv r| j        r|                                  n?| j         dk    r|                                  n| j         dk    r|                                  d S )Nr  r  r  r  r  )r  r  r   r!  r  r  rL   s    r1   #_do_actual_complete_type_is_changedz0CmfGanttTask._do_actual_complete_type_is_changed  s    $00++----&*JJJtOcJ335555&(22++----&/9966888rI   c                 @    | j         r|                                  d S d S rK   )r=   r   rL   s    r1   _do_const_duration_is_changedz*CmfGanttTask._do_const_duration_is_changed  s1      	(%%'''''	( 	(rI   c                    | j         r|                                  d S g ddd| j        gg}| j        s t          j                            |          r|                     d d           d S d| _        | 	                                 d S )NrU   rX   rR   r   TrF  r`  r#  )
r   r   r   r   r&   rf   r   ra  r   r.  )rG   _additional_task_filters     r1   _do_is_manual_is_chagnedz%CmfGanttTask._do_is_manual_is_chagned  s    > 	;%%''''' IHHD$),'# # ;v'?'D'DLc'D'd'd ;44X\4]]]]],5)88:::::rI   c                 h    | j         j        dk    r| j         r|                     d           d S d S d S )Nr<   unitsrK  )rF   r   rN  rL   s    r1   _do_task_sched_type_is_changedz+CmfGanttTask._do_task_sched_type_is_changed  sF    #z11d6J1  w 77777 2111rI   c                 n    | j         rd| _        | j        | _        d S | j        j        | _        d | _        d S Nr   )r&  r   r   r   defaultrL   s    r1   $_do_lock_sched_start_date_is_changedz1CmfGanttTask._do_lock_sched_start_date_is_changed  sB    % 	-(1D%(,(=D%%%(,(A(ID%(,D%%%rI   c                 n    | j         rd| _        | j        | _        d S | j        j        | _        d | _        d S r  )rM  r   r   r   r  rL   s    r1   %_do_lock_sched_finish_date_is_changedz2CmfGanttTask._do_lock_sched_finish_date_is_changed
  sB    & 	.)2D&)-)?D&&&)-)C)KD&)-D&&&rI   c                 (   |sd S |                      g d           |j                                        }|                     |                                            |                    | j                   |                    | j                   |                    | j	                   |
                                 |                    | j                   |                    d           |j        rc| j        s\|                     |j        j        d          | _        | j        j        r|                                  |                    |            n$|j        r| j        rn|                    |            |                    d           d S )Nr   r   r  r  Tr  r   r%  )r   r/   r4   rc   r  r   r  r   r  r  r  r  r  r  r   r   r   r   r   r'  rW  ra  r+   rG   r   r   s      r1   add_child_task_to_parent_taskz*CmfGanttTask.add_child_task_to_parent_task  s    	FSSSTTT'5::<<%%d&>&>&@&@AAA224?CCC224?CCC--d.>???44666--d.>???44D4III& 	Dt~ 	D$($A$A0AG$( %B % %D! $/ 744666CCDIIII( 	DT^ 	D==dCCC.....rI   c                    |sd S |                      g d           t                              d| j        j         d| j        j        j         d| j        j                    |j        	                                }|                     | 
                                           |                    | j                    |                    | j                    |                    | j                    |                                 |                    | j                    |                                 |                    | d           |                    d           d S )Nr  z*remove_child_task_from_parent_task gt_id: r  z$, gt.actual_work to be substracted: T)r`  r%  )r   r  r  ra   r   r   r   r  r/   r4   rc   r  r   r  r   r  r  r  r  r  ra  r+   r  s      r1   "remove_child_task_from_parent_taskz/CmfGanttTask.remove_child_task_from_parent_task0  s    	FSSSTTT	 NTW] N NVZV_VdVj N N595E5KN N 	O 	O 	O (5::<<%%d&>&>&@&@AAA22DO3CDDD22DO3CDDD--t/?.?@@@44666--t/?.?@@@4466699$RV9WWW.....rI   c                    t                                           5  | j        j        p| j        }|r|                     |           | j        j        p| j        }|r|                     |           d d d            d S # 1 swxY w Y   d S rK   )r)   rp  r   r   r   r  rA  r  )rG   
old_parent
new_parents      r1   _do_parent_task_is_changedz'CmfGanttTask._do_parent_task_is_changedC  s       "" 	? 	?)-C1CJ D77
CCC)-C1CJ ?22:>>>	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	?s   AA<<B B c                 <    t          j        j        | dg|R i | d S )Nupdated)r&   CmfEventdo_event)rG   argsrf  s      r1   _do_event_savezCmfGanttTask._do_event_saveP  s-     yB4BBB6BBBBBrI   c                     | |         j         S rK   )	log_level)rG   
field_namer  rf  s       r1   _get_field_log_levelz!CmfGanttTask._get_field_log_levelS  s    J))rI   c                    | j         rsd| _        d| _        |                                 rO|                                 }|j                                        }|| _        d| _        |                                  d S | j        j        rd| _        | j	        j
        r|                                  d S | j        j
        r|                                  d S | j        j
        r|                                  d S | j        j
        r,|                                  |s|                                  d S | j        j
        r|                                  d S | j        j
        r|                                  d S | j        j
        r|                                  d S | j        j
        r|                                  d S | j        j
        r,|                                  |s|                                  d S | j        j
        r|                                  d S | j        j
        r|                                  d S | j        j
        r|                                   d S | j!        j
        r| "                                 d S | j        j
        r,| #                                 |s|                                  d S | j$        j
        r,| %                                 |s|                                  d S | j&        j
        s| j        j
        r,| '                                 |s|                                  d S | j(        j
        s| j)        j
        r,| *                                 |s|                                  d S | j+        j
        r| ,                                 d S | j-        j
        r| .                                 d S | j/        j
        r| 0                                 d S | j1        j
        r| 2                                 | j3        j
        r| 4                                 | j5        j
        r,| 6                                 |s|                                  d S d S d S )Nr   r#  )7is_newr   r   rN   r   r4   r   r   r|   r   r   r  r  r  r  r  r   r{  r   r  r  r  r  r  r  r  r  r   r  r   r  r    r  r  r  r'  r   rQ  r   r.  r   r   r  r   r  r=   r  r&  r  r
  r  rM  r  rF   r  )rG   from_parent_changesr   r-  s       r1   _savezCmfGanttTask._saveW  s   ; 
	"#DDO**,, *$($?$?$A$A!*;*L*Q*Q*S*S'(?%,5)'')))F$, 	2(1D%& 	++---F"- 	22444F"- 	22444F) 	..000& 633555F* 	//111F& 	++---F& 	++---F* 	//111F?% 	**,,,& 633555F?% 	**,,,F!, 	11333F"- 	22444F$/ 	44666F + 	00222& 633555F!, 	11333& 633555F$/ 	43L3W 	44666& 633555F%0 	D4N4Y 	55777& 633555F>$ 	))+++F) 	..000F%0 	55777F&1 	966888&1 	966888* 	6//111& 63355555	6 	66 6rI   uS   Вычисление плановых работ по ресурсам задачиgantt_task_id)descriptionshow_bg_progressbarrY  rZ  r[  c           	      0   t                               d|             | d S t          j                            |           }|sd S |                    |                                           dd|j        gg dg}t          j        	                    |dg          D ]G}t                                          5  |                                 d d d            n# 1 swxY w Y   Ht          j        	                    dd|j        gg d          }|sd S |j        j        }|j        j        }t#          |j        j                  }t#          |j        j                  }t)          |          }	||z  |	z  }
|}d	}|	d
k    r
||	z  }||	z  }t                               d|j        j        j         d|             |D ],}|}|d	k    r||z  }d	}|                    |||||
d           -t                               d|  d|j        j        j                    d S )Nz)calc_resources_job start. gantt_task_id: r]  r!   rR   history_typerR   planr  rS   r!   personr   r   rX  z4calc_resources_job start_res_assignment. task.code: z gantt_task_id: T)
assignment	work_leftrH  r+  r  
create_tthz'calc_resources_job end. gantt_task_id: z task.code: )r  r  r&   r   r'   r   rc   r   CmfTimeTrackerHistoryre   r)   rp  deleteCmfTaskResAssignr   r   r   r~   r   r   r  r   _plan_resource_days)r  r.   r   tthassignmentsrH  r+  rJ  r  number_of_resourcesr  work_per_personwork_remainderr  r  s                  r1   calc_resources_jobzCmfGanttTask.calc_resources_job  s    	
KMKKLLL F(,,,>>
 	Fz==??@@@dJO41113/44G^L\4]] 	 	C$$&&  

               -228T:?:[:Z:Z:Z 3 \ \ 	F06
 28:4:;;z,233!+..$77"""&99O!$77N	  CzG[Ga  C  C  tA  C  C  	D  	D  	D% 	< 	<J'I!!^+	!"**j5>6@7B166: + < < < < 	
q-qqU_UdUiUoqqrrrrrs   8CC	 C	c                    d }d }	|j                             |                                | j        j        |o|                                          D ]}
|
j        j        }d}||                                k    r"t          |
                    |                    }t          |
j        j        |z
            }|dk    rnt          ||z                                t          d          t                    }||z  |z
  }||z  }||k     r|}|

                    t          |                    }|

                    t          |||z   |z  z                       p|                    dd          }|rt                              |j        | j        ||dt          |          d	          }t"                                          5  |                    d
           d d d            n# 1 swxY w Y   |s|}|'|                    |d          }||z   |k    r||z   ||<   ||z  }t          |                    t          d          t*                              dk    r|}	 n||	fS )N)rH  r   r+  r   r   rz      ;   )hourminuter  )r5   r!   rH  end_dater  
time_spentremaining_estimateF)r$   )r   	work_daysdater   r   r~   get_work_time_shiftinterval_total_minutesr   r   get_shifted_work_timer   replacer&   r  r  r   r)   rp  r+   r'   r   )rG   r  r  rH  r+  r  max_work_per_dayr  
start_timeend_timedaycur_date
time_shift
avail_timework_for_todaywork_for_today_remaindertth_start_datetth_end_dater  cur_max_work_for_todays                       r1   r  z CmfGanttTask._plan_resource_days  s   
&00JOO<M<MDHNDX=H=_[M]M]M_M_ 1 a a .	 .	C x~HJ:??,,,,$S%<%<Z%H%HII
 !;!AJ!NOOJQ$Z%%788AA'#,,YfAggN(2U(:n'L$11I>))!* 66s:GGN44SYqHquzGz9{5|5|}}  l  BP  BX  BX  ^`  ik  BX  Bl  BlL +22(/9-)!'">22'( 3   ((** + +HHEH***+ + + + + + + + + + + + + + +  ,+
+)9)=)=h)J)J&!$<<?UUU1?BZ1Z$X.'I9%%gcllZ%HHIIQNN' O 8##s   G((G,	/G,	c           
           fd}|sd S  j         dk    rd S t                              d j                    dd j        gg dg}t          t          j                            |dg                    d	k    }|sjt          j        	                    |d
g          D ]G}t                                          5  |                                 d d d            n# 1 swxY w Y   H j        j        } j        j        }t!           j        j                  }	t!           j        j                  }
|
}d}|+t          j        	                    dd j        gg d          }t          |           |            }|
sK j        j        r?|s= j        s j         dk    r)d _         j        j        r                     d           d}|	s9 j        j        r-|s+d _         j        j        r                     d           d}|rRt                              d j                    |r,t3          t          j        j        d j        j        i           d S  j        r|	r|
s|	}
|
|	z  z  }nx|
s|	}
|	s|
}	 j         dk    r	|
|	z  z  }n\ j         dk    r|dk    r|
|	z  z  }nB j         dk    r!|dk    r	|
|	z  z  }n(|dk    s|dk    r|	z  }
n j         dk    r|dk    r|	z  }
|
|z  dk    rd}|
}d}dk    r
|
z  }|
z  }g }g }i }|D ]}|}|dk    r||z  }d}                     |||||||           \  }}|                    |           |                    |           |                                |_        |                                |_         tC          |dz            |_"        t                                          5  |#                                 d d d            n# 1 swxY w Y   tI          |           _        tK          |           _        tC          tM          |'                                          |z  (                    t!          d          tR                               _        tC          |
           _         j         dk    rX|d v rR|	 j        j        k    r                     d           |dk    r&| j        j        k    r                     d           n% j         dk    r+|d!v r&| j        j        k    r                     d           n j         dk    r|d v rR|	 j        j        k    r                     d           |dk    r&| j        j        k    r                     d           |dk    r&| j        j        k    r                     d           na j         dk    rV|dk    r&|	 j        j        k    r                     d           |d!v r&| j        j        k    r                     d           |r,t3          t          j        j        d j        j        i           t                              d" j                    d S )#Nc                      j         rdS  dk    rdS j        sdS j        s	j        sdS j        rj        r	j        sdS dS )NTr   F)r   r   r   r   r   )r  rG   s   r1   check_exit_conditionsz;CmfGanttTask._calc_resources.<locals>.check_exit_conditions*  ss    # t"a''t( t& t t~ $/ $:M t5rI   r<   z&_calc_resources start. gantt_task_id: r!   rR   r  --rS      r  rX  r  r>   r   T)r  )r  z4_calc_resources exit_conditions_met. gantt_task_id: r  re  rD   rB   rJ  r  r  r@   i@8  )r  ry   r   rz   )r  r  )r  rJ  z'_calc_resources finish. gantt_task_id: )*rF   r  r  ra   r   r  r&   r  rg   re   r)   rp  r  r   r   r   r~   r   r   r  r   r   r   r   r  rm  r   r  r  r2  r  
date_startdate_endr   r  r+   r   r   sumvaluesr   r   )rG   rL  r  r  _tth_filter	havy_taskr  rH  r+  rJ  r  initial_workr  	do_returnr  r  start_times	end_timesr  r  r  r  r  r  s   `                      @r1   rN  zCmfGanttTask._calc_resources(  s(   	 	 	 	 	 	  	F:--F	BBBCCC $	25557 4::+W[V\:]]^^acc	 	!388UcTd8ee ! !((** ! !JJLLL! ! ! ! ! ! ! ! ! ! ! ! ! ! ! *0
,24.455t,-- 166xty>Y>^>^>^ 7 ` `K "+..))++	  	+ 	I 	~ U!59K!K!K&'#&1 U66t6TTTI  	D/3 	I 	DO) I..4.HHHI 	GGT47TTUUU w%f&9&LVegkgngtUuvvvvF> 	:    H_(;;EE     #'BBB,??%77 J..!H_0CCE%);;; F**!H_0CCEE"g--*1L1L#&99D%);;; J..#&99D5LX&&I"""&99O!$77N	% 	" 	"J'I!!^+	!"#'#;#;J	S]<GP`KT} $< $V $V J z***X&&&$.OO$5$5J!"*--//J"53;//J$$&& " "!!!" " " " " " " " " " " " " " " !$K 0 0!$Y!3'7'>'>'@'@#A#AE#I"S"ST[\_T`T`kx"S"y"yzzd))>11 111t28886646PPP G++@U0U0U22t2LLL!%777 5554?#88822t2LLL!%777 111t28886646PPP G++@U0U0U22t2LLL
**4?#88822t2LLL!%@@@&&8t7J7P+P+P22t2LLL 555,$/J_:_:_..4.HHH 	s!&"5"HRacgcjcpQqrrrr	C$'CCDDDDDs$   <CC!	$C!	O,,O0	3O0	c                     |                      |                                            | j        p| j        }|r|                     |           d S d S rK   )r   rc   r   r   r  rG   r!   s     r1   task_copy_hookzCmfGanttTask.task_copy_hook  s^    1133444!7T%7 	7..v66666	7 	7rI   c                     |                      |                                            |                                  |                     d|           |                     d           d S )Nr  )rL  r  Tr%  )r   rc   r(   rN  r+   )rG   r  s     r1   task_resources_changed_hookz(CmfGanttTask.task_resources_changed_hook  sg    1133444!!!7LLL		D	!!!!!rI   c                    |sd S |                      |                                            |                                  |r8| xj        |z  c_        | xj        |z  c_        |                     d           d S | xj        |z  c_        |d k    r| j        |z   | _        |                     d           |                     d           d S )NTr%  r  )r   rc   r(   r  r  r+   r
  r  )rG   r  r  from_tth_restores       r1   timetracker_add_work_hookz&CmfGanttTask.timetracker_add_work_hook  s     	F1133444!!! 	
*##z1##III%%%F:-%%*.*ADV*VD'...EEE 			D	!!!!!rI   c                     |                      |                                            |                                  | xj        |z  c_        |                                  |                     d           d S NTr%  )r   rc   r(   r  r  r+   r  s     r1   timetracker_add_cost_hookz&CmfGanttTask.timetracker_add_cost_hook  st    1133444!!!:-..000		D	!!!!!rI   c                 d   |                      |                                 ddgz              d}| j        j        r-| j        j        j        j        dk    r| j        j        | _        d}| j        r'| j        j        | _        |                                  d}|r| 	                    d           d S d S )Nru   task.parentF
CmfProjectTr%  )
r   rc   r   r!   r   
class_namer   r   check_gantt_projectr+   )rG   	need_saves     r1   task_parent_is_changed_hookz(CmfGanttTask.task_parent_is_changed_hook  s    11337Y[h6iijjj	9 		 0 6 A\ Q Q9+DLI 	!%!8D$$&&&I 	&III%%%%%	& 	&rI   c                 .    |                                   d S rK   )r  rL   s    r1   r  z2CmfGanttTask._do_timetracker_sched_work_is_changed  s    ""$$$$$rI   c                 :   |r|j         dk    r| j        s|                     |                                            |                                  | j                                         |                                  |                     d           d S |r|j         dk    r|r|j         dk    r|                     |                                            |                                  | j                                         d| _	        | 
                                 |                                  |                     d           |                                  d S |r|j         dk    r|r|j         dk    r|                     |                                            |                                  d | _        d| _	        | 
                                 |                                  |                     d           |                                  d S d S d S d S d S )NIN_PROGRESSTr%  r  ry   r   )r  r   r   rc   r(   set_nowr  r+   r    r  r  r  r	  )rG   
old_status
new_statuss      r1   task_status_is_changed_hookz(CmfGanttTask.task_status_is_changed_hook  s4     	*0MAA$J`AT5577888##%%%"**,,,11333III%%%F 	*0H<< =#-#9X#E#ET5577888##%%%#++---#&D 22444//111III%%%55777F 	*0H<< =#-#9X#E#ET5577888##%%%&*D##$D 22444//111III%%%55777F	 	<<<<#E#ErI   c                    |                      |                                            | j        st          dd           |                                  | j        s	 | j        j        | _        | j        j        | _	        | j        j
        s| j	        j
        rh|                                  |                                  |                                  |                                  |                     d           d	S d	S # t           $ rE}t          d| j        j         d| j        j         dt'          |           d           Y d	}~d	S d	}~ww xY wd	S )
u  
        Задача находится в списке с включенной опцией "Выставлять даты списка в плановые даты задач"
        Меняем плановые даты на даты из списков
        u?   У гант-задачи нет ссылки на задачу.Tr   r%  u(   Плановые даты задачи "r   u   ) не изменились                            при попытке выставления дат от спринтов из-за ошибки: "rh  N)r   rc   r   r   r(   r   plan_start_dater   plan_end_dater   r   rS  rD  r{  r5  r+   CmfAbortErrorr   r   str)rG   es     r1   task_plan_dates_is_changed_hookz,CmfGanttTask.task_plan_dates_is_changed_hook5  s   
 	1133444y 	eW_cdddd!!!# 	KK(,	(A%)-)@&(3 .t7M7X .335556688877999,,...III-----. . ! K K K JTY^ J JX\XaXf J J AD  EF  AG  AGJ J J K K K K K K K K KK	K 	Ks   B D   
E
:E

Ec                     |                      |                                            |                                  |                     d           d S r/  )r   rc   r5  r+   rL   s    r1   task_logic_type_is_changed_hookz,CmfGanttTask.task_logic_type_is_changed_hookM  sN    1133444  """		D	!!!!!rI   c                     |                      |                                            | j        j        | _        | j        j        r|                                  d S d S rK   )r   rc   r   r   r   r+   rL   s    r1    task_parent_task_is_changed_hookz-CmfGanttTask.task_parent_task_is_changed_hookR  sX    113344490& 	IIKKKKK	 	rI   c                     |                      |                                            | j        j        | _        |                                  |                     d           d S r/  )r   rc   r   r   r5  r+   rL   s    r1   "task_gantt_project_is_changed_hookz/CmfGanttTask.task_gantt_project_is_changed_hookX  s[    1133444!Y4  """		D	!!!!!rI   c                     |                      |                                            | j        r&d | _        d| _        |                     d           d S d S )Nr#  Tr%  )r   rc   r   r   r+   rL   s    r1   $task_has_child_tasks_is_changed_hookz1CmfGanttTask.task_has_child_tasks_is_changed_hook^  sa    1133444$ 	&(,D%(1D%III%%%%%	& 	&rI   c                     |                      |                                            |                     d d           |                                  |                     d           d S )NTr  r%  )r   rc   ra  rC  r+   rL   s    r1   *additional_children_relations_changed_hookz7CmfGanttTask.additional_children_relations_changed_hooke  sh    1133444,,PT,UUU'')))		D	!!!!!rI   c                 L    | j         j        rd| _         | xj         |z  c_         d S r   )r  r|   )rG   r  s     r1   r  z CmfGanttTask.from_child_add_workk  2    # 	! DJ&rI   c                 L    | j         j        rd| _         | xj         |z  c_         d S r   )r  r|   r  s     r1   r  z CmfGanttTask.from_child_add_costp  rQ  rI   c           	      R   | j         j        rd| _         | xj         |z  c_         | j        s*| j         | _        | j        j        pd| j        j        pdz
  }n}| j         | j        k    sP| j         dz   d| j         dz   d}| j        dz   d| j        dz   d}t          d| d| d| j         dd	
           | j         j        pd| j         j        pdz
  }|                                 r| j        j	        dk    rt                                          5  |                                 }|                    |                                            |                    |           |                                 |                    dd	           d d d            d S # 1 swxY w Y   d S d S d S )Nr   r  r  r  u;   Превысили План на Трудозатраты ( <= +   ) в родительской задаче ub   . Увеличьте в ней план или введите меньше Трудозатрат.Tr   rP   Frk  )r  r|   rA   r   rA  r   r   r   rN   rd   r)   rp  r   rc   r  rC  r+   )rG   r  r  r   r   s        r1   r  z%CmfGanttTask.from_child_agregate_worku  sp   $ 	" !DZ' 	U"/DO/-2t7J7OaPJJ$77"&"3r"9XXd>ORT>TXXX $2 5RR$/B:NRRR
 Xd  jt  GKy   GKL L L L +/419J9N9SRSTJ &&(( 	ITY-CG[-[-[$$&& I I$($?$?$A$A!!--d.F.F.H.HIII!:::FFF!<<>>>!&&%4&HHHI I I I I I I I I I I I I I I I I I	I 	I-[-[s   A<FFFc           	         | j         j        rd| _         | xj         |z  c_         | j        s| j         | _        n:| j         | j        k    s*t	          d| j          d| j         d| j         dd           |                                 r| j        j        dk    r| j         j        pd| j         j	        pdz
  }t                                          5  |                                 }|                    |                                            |                    |           |                    d	           d d d            d S # 1 swxY w Y   d S d S d S )
Nr   u1   Превысили План на Расходы (rT  rU  u[   . Увеличьте в ней план или введите меньше РасходовTr   rP   r%  )r  r|   r  r   r   r   rN   rd   rA  r   r)   rp  r   rc   r  r+   r  s      r1   r  z%CmfGanttTask.from_child_agregate_cost  s   $ 	" !DZ' 	&"/DOO$77 ndN_ n neiet n nGKyn n n $& & & & &&(( 	7TY-CG[-[-[+/419J9N9SRSTJ$$&& 7 7$($?$?$A$A!!--d.F.F.H.HIII!:::FFF!&&&666	7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7	7 	7-[-[s   A'E  EEc                 0    |                      |           dS )u   
        Оповестить родителя, что ему нужно пересчитать свой агрегат actual_complete
        N)r!  )rG   r  s     r1   !from_child_update_actual_completez.CmfGanttTask.from_child_update_actual_complete  s     	++,ABBBBBrI   c                 `   |                                  sdS t                                          5  |                                  }|                    |                                            |                    |            |                    d           ddd           n# 1 swxY w Y   dS )uP  
        Оповещение родителя.
        Передаем себя, т.к. мы еще можем быть не сохранены и родитель не сможет получить наши данные
        Другой вариант: опочещать через отдельный таск в celery
        NFr  )rN   r)   rp  r   rc   rX  r+   )rG   r   s     r1   r	  z1CmfGanttTask.notify_parent_update_actual_complete  s     **,, 	F  "" 	5 	5 $ ; ; = =))$*B*B*D*DEEE??EEE ""e"444	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	s   A'B##B'*B'c                    | j         s| j        ryd |                     d          D             }|h dz
  }|rP| j        j                                         | j        j        r&| j        j                            d| j                   | j        j        r| j        rt          dd           | j
        j        r| j        rt          d	d           | j        j        s| j        j        r/| j        r(| j        r!| j        | j        k     rt          d
d           | j        j        r#| j        s| j        dv rt          dd           d S d S d S d S )Nc                     h | ]\  }}|S rZ   rZ   )r^   k_s      r1   	<setcomp>z0CmfGanttTask.check_user_input.<locals>.<setcomp>  s    JJJFQaJJJrI   Tr   >   r   r   parent_task_idgantt_project_idzPPP-TSK-SCHEDULE)obju   Нельзя менять поле "Фактические трудозатраты" у Summary-задач. Используйте поле "Фактические трудозатраты по собственным ресурсам задачи"r   u   Нельзя менять поле "Фактические Затраты" у Summary-задач. Используйте поле "Фактические Затраты по собственным ресурсам задачи"u\   Нельзя выставить Дату начала позже Даты окончанияr  u   Этот вариант рассчета процента завершения можно использовать только у Summary-задач)r  r   itemsr   r   r4   check_project_role_accessr  r   r   r  r   r   r  )rG   changed_fieldss     r1   check_user_inputzCmfGanttTask.check_user_input  s   { 	ct 	cJJdjjDj.I.IJJJN ,.t.t.ttN c	!&&(((9$ cI%??@RX\Xa?bbb& 	q4+? 	q d lpq q q q& 	g4+? 	g Z bfg g g g$/ 	J43M3X 	J( JT-G J-0III|  EI  J  J  J  J$/ 	&' &D,EIi,i,i  r $& & & & & &	& 	&& &,i,irI   c                    | j         j        rd| _         | j        j        rd| _        | j        j        rd| _        | j        j        rd| _        | j        j        rd| _        | j        j        rd| _        | j        j        rd| _        | j        j        rd| _        | j	        j        rd| _	        | j
        j        rd| _
        | j        j        rd| _        | j        j        rd| _        | j        j        r	d| _        d S d S r   )r  r|   r  r   r  r   r   r  r   r  r  constrain_slackconstrain_slack_pcttotal_slackrL   s    r1   r(   zCmfGanttTask.fix_null_variables  s,   # 	! D$ 	" !D?" 	 DO# 	! D& 	$"#D' 	%#$D $ 	" !D?" 	 DO"* 	(&'D#' 	%#$D ' 	%#$D #+ 	)'(D$# 	! D	! 	!rI   r   c                 T   t                               d| j         d|            | j        j        dk    rd S | j        j        r| j        r| j        j        r$| j        | j        j        k    rd}| j        j        }n| j        j        s| j        ry| j        j        	                    | 
                                           | j        j                            | j        d           | j        j                            d           d S t          | j        p| j        p| j        p| j        p| j                  }|sK|sI| j        s| j        j        dv s4| j        s|s+| j        j        r<| j        r6| j        | j        j        k    r"|rd S |r4|| _        | j        | j        _        | j                            d           nQ| j        j        sE| j                                         | j        j        | _        | j                            d           |s| j        rz|                                 }|D ]c}|j        r|j        | j        k    rJ|                    | j        d|dz   	           |                                 |                    d           d|s|                                 r|                                 }	|		                    | 
                                           |	j        j        dk    ra|	j        r|	j        | j        k    rJ|	                    | j        d|dz
  
           |	                                 |	                    d           | j        sM| j        j        r|                     | j        j                   |                     | j                   d S d S d S d S d S )Nz!check_gantt_project: gantt_task: z	, level: rP   T)r   r   r%  )z	task.epicztask.subprojectrX  )r   r  level)r   r   rl  )r  r  ra   r   rd   r   r   r   r/   r   rc   r5  r+   boolr   r   r   r   r   r   _calc_gantt_projectr   ro   _calc_outline_numberrN   r  r  )
rG   r  r   r   from_importrl  plan_fields_are_usedrE  rF  r   s
             r1   r5  z CmfGanttTask.check_gantt_project  sk    	
MDGMMeMMNNN9!%999F & 	 
#1 	d6HDL\Lj6j6j(,'$($4$BMM)7 D<N $2>>t?W?W?Y?YZZZ$2FFUYUg  }AF  B  B  B$277$7GGGF#! %"   
  
  -	G!-	G &-	G ,09+AEe+e+e& ,f+? ,f"- ,f262D ,fIMI[_c_q_uIuIu  	/%2"*.*<	'	....'2 /	--///%)Y%<"	...% 8$*> 8"<<>>"- 8 8J%3 8z7OSWSe7e7e"66TEWmqy~  BC  zC6  D  D  D"77999"$777 (
?//11
? %)$?$?$A$A!!--d.F.F.H.HIII$)6:NNN,: ?>O>]aeas>s>s)==DL^sw  @E  HI  @I=  J  J  J)>>@@@)...>>># G%) T;;D<N<RSSS2243EFFFFFU ,f+e+e+eIuIuJG GrI   c                 N   t                               d| j        j        j         d| j        j        j         d|            |dk    rt          dd           |s| j        }dd	| j        gg d
g}d t          j	        
                    |ddg          D             }d }t          j                            ddt          |                                          gg d          }|D ]a}|j        j        }||j        j        j                 }	|s(|	r-|j        j        }
t          j                            |
||	          }||k    r|} nb|s[| j        rT| j        j        }|                    |                                           |j        s|                    ||dz             }|S )Nz0_get_task_blocking_back_movement start task_id: r  z
), depth: ry   uY   DEV: Защита от рекурсии: _get_task_blocking_back_movement: if depth > 100Tr   rX   rR   rV   rR   zsystem.finish:startc                 2    i | ]}|j         j        |j        S rZ   )r[   ra   r$  r]   s     r1   
<dictcomp>zACmfGanttTask._get_task_blocking_back_movement.<locals>.<dictcomp>I	  s3      "i  "i  "i#,/33D  "i  "i  "irI   r[   r$  rS   r1  rb   )z	task.nameztask.idr   r;  rX  )target_datedepth)r  r  r   r   r   r   r   r   r&   rf   rg   r   re   keysr   ra   r   r   r   r   r   r/   r   rc   r    _get_task_blocking_back_movement)rG   rv  rw  
_filter_inbefore_tasks_with_lagsblocking_gantt_taskbefore_gantt_tasksbefore_gantt_taskr+  r$  r   r   s               r1   ry  z-CmfGanttTask._get_task_blocking_back_movement?	  sZ   	  C49>CW  C  C[_[d[i[o  C  C  |A  C  C  	D  	D  	D3;;qy}~~~~ 	0/K $	24g4g4gh
 "i  "iPVPhPnPn  wA  KU  Wf  JgPn  Qh  Qh  "i  "i  "i"#055tT*@*E*E*G*G%H%HI]]] 6 
 
 "4 	 	+=CK23D3I3L3RSM  l,4=$0EEhP[]jkk[((&7# ) # 	Ct'7 	C $ 0 >))*;*O*O*Q*QRRR$. C&7&X&Xepx}  AB  yB&X  'C  'C#""rI   c                 d   | j         j        r t                              d| j        j        j         d| j        j        j         d| d| j         j         d| j         j	         
           | j         j        r]| j         j	        rQ| j         j        | j         j	        k     r7|r5| 
                                }|rt          d|j        j         dd	           d
d| j        gg dg}t          j                            |          r0t          t          j        j        d| j        j        i           d S d S d S )Nz-_check_start_finish_relations start task_id: r  z), from_save: z sched_finish_date_new: z, self.sched_finish_date.old: uB   Перемещение заблокировано задачей "uk   " с исходящей связью ОН. Удалите связь и попробуйте еще раз.Tr   r[   rR   rs  r   r1  re  )r   r   r  r  r   r   r   r   rA  r   ry  r   r&   rf   r   rm  sort_task_by_order_relationsra   )rG   	from_saveblocking_task_filter_outs       r1   rD  z*CmfGanttTask._check_start_finish_relationsg	  s   !, 	GG FDINDX F F\`\e\j\p F F  AJ F F/3/E/IF Fimi  jDF F G G G &*o/3/E/Io*.1G1KKK L !% E E G G  o bcpcucz b b bimo o o o 'di8:m:m:mnK',,K,@@ %f&>&[enptpyp|d}~~~~~~	 	 rI   )rl  r  from_sort_orderc                &   |r!|                                    | j        |i | |                     |           | j        j        r| j                            d           |                                  |                                  |                                  | 	                                  t                      j        |i |}| j        j        rKt                              | j        | j                                        d                                           | j        j        rKt                              | j        | j                                        d                                           |s|                     d           |S )N)r  Tr%     )r!   r   r  )r  )rf  r  r  r   r   r+   r5  r(   _alert_task_agile_plan_datesro  rv   r   r&   
CmfComment	html_diffr   rD  )rG   rl  r  r  r  rf  r   rw   s          r1   r+   zCmfGanttTask.savez	  s    	1!!###D0000

':
;;; 9 	+INNTN***  """!!!))+++!!###egglD+F++ + 	y*4466    dfff!, 	y+5577    dfff 	?...>>>
rI   c                 b    |                                    t                      j        |i | d S rK   )r   rv   _save_import)rG   r  rf  rw   s      r1   r  zCmfGanttTask._save_import	  s7    !!###d-f-----rI   )TEXKOM_db_deletefrom_task_deletec                r   |                      g d           | j        r|                     | j                   |rt                              | j                   t          j        	                    | j        d          D ]9}t                              |           d |_
        |                    d           :n*| j        r#| j        j
        | k    r|st          dd           | j        r1| j        j
        | k    r!|                     | j        p| j                    t                      j        |d|i|S )N)task.op_gantt_taskztask.cmf_deletedr   r   outline_index_numrq   T)r/   include_deletedr%  uY   Нельзя удалять Оперативную гант задачу у задачи!r   r  )r   r   outline_remover   r  r  ra   r&   r  re   r/   r+   r   r   r  rv   r  )rG   r  r  r  rf  r   rw   s         r1   r  zCmfGanttTask.delete	  so    L L L 	M 	M 	M 	2 0111  
	GGGDG++$'SW+XX * *%)"		D	))))* y GTY4<<' Gy  BF  G  G  G  G9 	\0D8833D4D4ZHZ[[[uww~tQ6FQ&QQQrI   c                     |                      g d            t                      j        |i |}| j        r1| j        j        | k    r!|                     | j        p| j                   |S )N)r  r   r   )r   rv   restorer   r/   r  r   r   )rG   r  rf  r   rw   s       r1   r  zCmfGanttTask.restore	  sv    OOOPPPeggot-f--9 	W0D88..t/?/U4CUVVV
rI   c                      t                      j        di | | j        rd S t                              d           t
          j                            | dd           t                              d           d S )N_CmfAutomationCrudTrigger startupdatebefore_save_CmfAutomationCrudTrigger endrZ   )rv   before_save_hookr  r  r  r&   CmfAutomationCrudTrigger	crud_hookrG   rf  rw   s     r1   r  zCmfGanttTask.before_save_hook	  sv      **6***; 	F	1222'11$-PPP	/00000rI   c                      t                      j        di | | j        rd S t                              d           t
          j                            | dd           t                              d           d S )Nr  r  
after_saver  rZ   )rv   before_save_data_hookr  r  r  r&   r  r  r  s     r1   r  z"CmfGanttTask.before_save_data_hook	  sv    %%/////; 	F	1222'11$,OOO	/00000rI   r  c           	      v   | j                                          t          j        r| j         sd S t          j        t          j        j        j        dg|| j        j        |                     d          t          j        | j         j        j        d}t          d|d          ||d         |d         g           d S )Nproject_notifyTr_  )initiatorSessionTabIdinitiatorCurrentPersonactioninitiatorActioninitiatorObjIdinitiatorObjChangedFieldsu   initiatorСomponentId	projectIdzproject_notify-r  )roomevent_persons)
r   r4   r  session_tab_idcurrent_personra   r   rx  component_idcmf_emit_event)rG   initiator_actionevents      r1   r  zCmfGanttTask.project_notify	  s     		 F &'%5&'&6&9&?'(/"gm)-d)C)C%&^.
 
 	={);==u5Q\K]nst  oA  nB  	C  	C  	C  	C  	C  	CrI   c                    | j         j        s| j        j        sd S d}d}| j        j        r| j         r| j         | j        j        k     rd}| j        j        r| j        r| j        | j        j        k    rd}g }|s|rr| j                            ddg           | j        j        D ]I}|r|j        r| j         |j        k     s|r,|j        r%| j        |j        k    r|                    |           J|rtd| j        j	         d| j        j
         dt          |          dk    rd	nd
 d}|D ]}|d|j	         d|j
         dz  }t          |                    d                     d S d S )NFTzlists.plan_start_datezlists.plan_end_dateu   Задача "r   uI   ) выходит за диапазон плановых дат спискrX  u   аu   oв: r  z),,)r   r   r   r   r@  rA  r   listsr2  r   r   r  r   rstrip)rG   alert_start_datealert_end_datealert_lists	task_listrV  lsts          r1   r  z)CmfGanttTask._alert_task_agile_plan_dates	  s   %0 	D4J4U 	F 9$ 	()> 	($ty'@@@#' 9" 	&t'= 	&%	(???!% 	2~ 	2I!!#:<Q"RSSS!Y_ 2 2	%2*3*C2HLH]`i`yHyHy& Iz+4+B IzGKG]`i`wGwGw&&y111 	'IDIN I Ity~ I Iehiteueuyzezez]a]a  AFI I IC" 4 433833sx3333cjjoo&&&&&	' 	'rI   c                 ~   | j         j        dk    rd S ddddd}d }|                                D ]}t          | |          }|j        r|j        rd }d }|dv rEd}|j        r|j        d	z  |j        d	z  }}|d
d|d
d}|j        d	z  |j        d	z  }
}	|	d
d|
d
d}|dv r|s|                                 }|j        }|rC|                    t                                }|t          j        |j        j                  z   }|j                            t                                }|t          j        |j        j                  z   }t          |j        j        d	z  d	          \  }}d|dd|d
}|                    d           d| }|r|                    d           d| nd}t!          d| j         j         d| j         j         d||          d|p|j         d|p|j         d           |j        s:|j        r3t!          d| j         j         d| j         j         d||          d           d S )NrP   u)   Плановая длительностьu)   Плановые трудозатратыu&   Плановая дата началаu,   Плановая дата окончания)r   r   r   r   )r   r   u   Нетr  02dr  u   мин)r   r   r   zUTC z+03dr  z%Y.%m.%d, %H:%Mr  u   DEV: У задачи r  u   ) изменено поле "z":                        c u    на r   u.   ) сброшено значение поля "z".)r   rd   rx  r   r   rA  r   r   
astimezoner   r   r   r   r   divmodstrftimer   r   r   )rG   r"   r   r  r0   new_value_strold_value_strold_hour
old_minutenew_hour
new_minutedate_olddate_newr   r  time_suffixs                   r1   rC  z'CmfGanttTask._alert_changed_plan_fields
  sH   9!%999F JE H!O	
 
  ++-- &	^ &	^JD*--E #^9 "^$(M$(M!%EEE(0 9 W389?EIPRNjH/7,V,V,V
,V,V,V,VM/4yB	B*+3(R(R(RJ(R(R(R(R!%NNN' <'+'9'9';';H#(9# `'/':':577'C'CH'/",xGXG^2_2_2_'_H#(9#7#7#@#@#+bl8CTCZ.[.[.[#['-h.?.E.KR'P'Pf&ET&E&E&E&E&E&E+3+<+<=N+O+O(_(_R](_(_ck(y8+<+<=N+O+O(_(_R](_(_(_qy [din [ [	 [ [u{  }G  vH [ [(5EI[ [=J=Wei[ [ [ \ \ \ \ ^uy ^  ]din  ]  ]	  ]  ]  GM  NX  GY  ]  ]  ]  ^  ^  ^M&	^ &	^rI   c                 l   | j         j        s| j        j        sd S | j        j        dk    rd| _        d| _        d | _        d S | j         j        rJ| j         sC| j         j        r5| j        }| j        j        r| j        j        }| 	                    |           d S | j         sd| _        d| _        d | _        d S | j         j        r)| j         r"| j         j        s| 
                                 d S | j        j        r=| j        s | 	                    | j        j                   | 
                                 d S d S )NrP   r   )remove_from)r   r   r   r   rd   outline_numberoutline_parent_strr  r   r  outline_insert_downr  r'  s     r1   ro  z!CmfGanttTask._calc_outline_number[
  sr   )	*	 F9!%999"$D&(D#%)D"F( 	1C 	!% 8)#. 2!-1F###777F! 	"$D&(D#%)D"F( 	T-? 	HZH^ 	$$&&&F& 	'; F##0@0D#EEE$$&&&&&	' 	'rI   c                    |                      | j        j        | j        j                   d| _        | j        r| j        j        j        | _        t                                          5  t          j
                            dgg dd| j        gdd| j        gg ddd| j        gg	          j        }d d d            n# 1 swxY w Y   |r|d
z   | _        nd
| _        | j        r&| j        r| j        pd d| j        j        d| _        n| j        j        d| _        | j        j        rOt#          t          j
        j        | j        j        j        g| j        j        g| j        j        j        g           d S d S )Nr   max__outline_index_numr   r  r   )r!   r  Nra   r=  )r"   order_byrT   rX  r   06r  )_outline_lock_lvlr   ra   r   r  r/   r  r)   rp  r&   r   r'   r  r  r   r   r   rm  _outline_recalc_childrens)rG   	max_indexs     r1   r  z CmfGanttTask.outline_insert_down}
  s   t14d6F6IJJJ"$ 	T&*&6&D&SD#  "" 	% 	%+//01"C)9:$c4+=>)))4)	 0 	 	 % 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	%  	'%.]D""%&D" 	G& k *.)@)FB&j&jI_Ie&j&j&j#%)%;%A"F"FD9$ 	\!&"5"OX\XaXdXjWknrnun{m|  C  Q  T  Z  W[  \  \  \  \  \  \	\ 	\s   (AB;;B?B?c           
         |                      g d           |                     | j        j        | j        j                   d }|rDt
          j                            |ddg          }|j        | j        k    rt          dd           | j	        j
        }|sd}d| _	        d}d}|}d}n<|j        j	        j
        }||k     rd}|dz   | _	        |dz   }|}d}nd	}|| _	        |}|}d
}| j        r| j        pd d| j	        j
        d| _        n| j	        j
        d| _        d}	t
          j        j        j                                                            |	| j        j        j
        | j        j        j
        | j        j
        |||d          }
d |
D             }d |
D             }| j        j        r$|                    | j        j        j
                   |r4t-          t
          j        j        ||| j        j        j
        g           d S d S )N)r   r   r  r  rs   zop_gantt_task.outline_index_numr   r^  u   outline_insert_after можно вызывать только для задач на том же уровне. Сначала измените parent_taskTr   rX  Fr   r   r  a  UPDATE cmf_gantt_task SET
            outline_index_num = outline_index_num + :i,
            outline_number = (CASE WHEN outline_parent_str = '' or outline_parent_str is null THEN to_char(outline_index_num + :i, 'FM000000') ELSE concat(outline_parent_str, '.', to_char(outline_index_num + :i, 'FM000000')) END)
        WHERE
            (parent_task_id = :parent_task_id or (:parent_task_id is null and parent_task_id is null))
            AND gantt_project_id = :gantt_project_id
            AND outline_index_num >= :from_outline_index_num
            AND outline_index_num <= :to_outline_index_num
            AND parent_id is null
            AND id != :id
        RETURNING task_id, id
        )r`  ra  ra   from_outline_index_numto_outline_index_numic                     g | ]
}|d          S r1  rZ   r^   rs     r1   r`   z5CmfGanttTask.outline_insert_after.<locals>.<listcomp>
      ///aQy\///rI   c                     g | ]
}|d          S r]  rZ   r  s     r1   r`   z5CmfGanttTask.outline_insert_after.<locals>.<listcomp>
      000q1T7000rI   r  )r   r  r   ra   r   r&   r  r'   r   r  r   r/   r  r  	CmfPersondp_ddSessionexecuter   r   r2  rm  r   r  )rG   prev_task_id	prev_taskold_outline_index_numprev_outline_index_num	insert_upr  r  r  sqlr   	child_idschild_gantt_idss                r1   r   z!CmfGanttTask.outline_insert_after
  s    	|||}}}t14d6F6IJJJ	 	E**lDegtCu*vvI$(888  x  @D  E  E  E  E
 !% 6 < 	%&"%&D"I%&"#8 AA%.%<%N%T"%(=== 	)?!)C&)?!)C&'<$!	)?&)>&'=$  	G%)%<%B"f"fTE[Ea"f"f"fD%)%;%A"F"FD !%--//77".17 $ 2 5 ;'-&<$8>
 >
   0/3///	00C0009$ 	1TY\/000 	Q!&"5"OW`bqsw  tF  tI  tO  WP  Q  Q  Q  Q  Q  Q	Q 	QrI   c                    | j         sd S d }|r|j        j        }|                     | j        j        |           d| _        d| _        t          | j                   }d | _         d}t          j	        j
        j                                                            ||| j        j        j        || j        j        d          }d |D             }d |D             }|r2t          t          j        j        ||| j        j        j        g           | j        rS| j        j        rIt          j                            | j        j        j        dg          j        | j        j        _        d S d S d S )	Nr   a}  UPDATE cmf_gantt_task SET
            outline_index_num = outline_index_num - 1,
            outline_number = (CASE WHEN outline_parent_str = '' or outline_parent_str is null THEN to_char(outline_index_num - 1, 'FM000000') ELSE concat(outline_parent_str, '.', to_char(outline_index_num - 1, 'FM000000')) END)
        WHERE
            (parent_task_id = :parent_task_id or (:parent_task_id is null and parent_task_id is null))
            AND gantt_project_id = :gantt_project_id
            AND outline_index_num >= :old_outline_index_num
            AND parent_id is null
            AND id != :id
        RETURNING task_id, id
        )r`  ra  r  ra   c                     g | ]
}|d          S r  rZ   r  s     r1   r`   z/CmfGanttTask.outline_remove.<locals>.<listcomp>   r  rI   c                     g | ]
}|d          S r]  rZ   r  s     r1   r`   z/CmfGanttTask.outline_remove.<locals>.<listcomp>  r  rI   r  r  r^  )r  ra   r   r  r   r  r  r   r&   r  r  r  r  r  rm  r   r  r   r/   r   )rG   r  remove_from_idr  r  r   r  r  s           r1   r  zCmfGanttTask.outline_remove
  s   % 	F 	2(^1Nt14nEEE"$  #D$: ; ;!%
 !%--//77, $ 2 5 ;%:'-	>
 >
   0/3///	00C000 	Q!&"5"OW`bqsw  tF  tI  tO  WP  Q  Q  Q  Q 	y 0 > 	y#((D,<,J,MWgVh(iix *999	y 	y 	y 	yrI   c                 F    t                               d| d|            d S )NOUTLINE_NUMBER_r]  )r)   cache_obj_lock_get)r,   ra  r`  s      r1   r  zCmfGanttTask._outline_lock_lvl	  s0     	""#X5E#X#X#X#XYYYYYrI   uY   Вычисление структурных номеров у дочерних задач)r  r[  c                    t                               d           t          j        j                            t          j        j        |            t          j        j                            t          j	        j        |           g g fdt                               d            |            t                               d           t          j        j                            t          j        j                   t          j        j                            t          j	        j                   t                               d           d S )Nz)_outline_recalc_childrens init invalidatec                 T   t                               dt          |                       | D ]"}t          j                            |           #t                               d           d}t          j        j        j        	                                
                    |t          |           d          }g }|D ][}|d         r|                    |d                                        |d                                        |d                    \|r 	|           d S d S )Nz3_outline_recalc_childrens recalc_subtree start len=z2_outline_recalc_childrens recalc_subtree locks seta  UPDATE cmf_gantt_task SET
                outline_parent_str = pg.outline_number,
                outline_number = (CASE WHEN pg.outline_number = '' or pg.outline_number is null THEN to_char(ugt.outline_index_num, 'FM000000') ELSE concat(pg.outline_number, '.', to_char(ugt.outline_index_num, 'FM000000')) END )
            FROM
                cmf_gantt_task ugt
                LEFT JOIN cmf_task pt ON pt.id = ugt.parent_task_id
                LEFT JOIN cmf_gantt_task pg ON pt.op_gantt_task_id = pg.id
            WHERE
                ugt.parent_task_id IN :parent_task_id_list
                AND ugt.gantt_project_id = :gantt_project_id
                AND ugt.id = cmf_gantt_task.id
                AND ugt.parent_id is null
            RETURNING ugt.task_id, ugt.id, (select cmf_task.has_child_tasks from cmf_task where cmf_task.op_gantt_task_id = ugt.id) as has_child_tasks
            )parent_task_id_listra  r   r1  ra   )r  r  r  r&   r   r  r  r  r  r  r  tupler2  )
parent_id_list	parent_idr  r   recursive_parent_id_listtfinish_gantt_invalidatefinish_invalidatera  recalc_subtrees
         r1   r  z>CmfGanttTask._outline_recalc_childrens.<locals>.recalc_subtree  sP   GG_#nJ]J]__```+ S S	#556F	RRRRGGIJJJC "%)1133;;C',^'<'<$4B B  C (*$ 8 8&' B,33AiLAAA!((9666'..qw7777' 97888889 9rI   z._outline_recalc_childrens start recalc_subtreez+_outline_recalc_childrens finish invalidatez_outline_recalc_childrens end)
r  r  cmfapp	CMF_CACHEinvalidate_idsr&   r  r4  r   )idsgantt_task_idsra  r   r  r  s     `@@@r1   r  z&CmfGanttTask._outline_recalc_childrens  s%   
 	
<===(()BCHHH(()<)GXXX"$	9 	9 	9 	9 	9 	9 	9 	9D 	
ABBBs	>???(()BDUVVV(()<)GI`aaa	011111rI   uB   Перевычисление структурных номеровc                    | r| g}n2t           j                            ddgg dd          }d |D             }t                              dt          |                      |D ]} t                              d|  d	           t                      }|                    d            |rL|                                }t                              d|  d
|            d}t           j	        j
        j                                                            ||| d          }t                      }|D ]@}|d         r|                    |d                    |                    |d                    At                       t                              d           t          j        j                            t           j        j        t)          |                     t                              d           |Ld S )Nr  ra   )rd   r  rP   T)r"   rT   include_systemc                     g | ]	}|j         
S rZ   r]  r  s     r1   r`   z6CmfGanttTask._outline_force_recalc.<locals>.<listcomp>K  s    $7$7$7aQT$7$7$7rI   u<   _outline_force_recalc Всего гант-проектов: u/   _outline_force_recalc обрабатываем u   . Уровень 0u   . Дочки от u
  WITH gt AS (
                    select g.id, g.task_id, g.parent_task_id, x.num
                    from
                        cmf_gantt_task as g
                        inner join cmf_task t ON t.id=g.task_id
                        inner join unnest(array(
                            SELECT cmf_gantt_task.id from cmf_gantt_task inner join cmf_task ON cmf_task.id=cmf_gantt_task.task_id
                            WHERE
                                -- Основной WHERE. Нужен чтобы верно рассчитались номера
                                cmf_gantt_task.parent_task_id = :parent_task_id OR (:parent_task_id is null and cmf_gantt_task.parent_task_id is null)
                                AND cmf_gantt_task.gantt_project_id = :gantt_project_id
                                AND cmf_gantt_task.cmf_deleted = false
                                AND cmf_gantt_task.parent_id is null
                            ORDER BY
                                cmf_gantt_task.outline_number, cmf_task.orderno, cmf_gantt_task.cmf_created_at
                        )) WITH ORDINALITY AS x(id, num) ON x.id=g.id
                        WHERE
                            -- Дубль WHERE. Нужно чтобы PG не селектил все гант-таски в cmf_gantt_task as g
                            g.parent_task_id = :parent_task_id OR (:parent_task_id is null and g.parent_task_id is null)
                            AND g.gantt_project_id = :gantt_project_id
                            AND g.cmf_deleted = false
                            AND g.parent_id is null
                        ORDER BY
                            -- Дубль сортировки
                            g.outline_number, t.orderno, g.cmf_created_at
                )
                UPDATE cmf_gantt_task SET
                    outline_index_num = gt.num,
                    outline_parent_str = pg.outline_number,
                    outline_number = (CASE WHEN pg.outline_number = '' or pg.outline_number is null THEN to_char(gt.num, 'FM000000') ELSE concat(pg.outline_number, '.', to_char(gt.num, 'FM000000')) END )
                FROM
                    gt
                    LEFT JOIN cmf_task pt ON pt.id = gt.parent_task_id
                    LEFT JOIN cmf_gantt_task pg ON pt.op_gantt_task_id = pg.id
                WHERE
                    gt.id = cmf_gantt_task.id
                RETURNING gt.task_id, (select cmf_task.has_child_tasks from cmf_task where cmf_task.id = gt.task_id) as has_child_tasks
                )r`  ra  r   r1  z&_outline_force_recalc cache invalidatez-_outline_force_recalc finish cache invalidate)r&   r  rg   r  r  r  rn  ro  popr  r  data_driverr  r  
cmf_commitr  r  r  r  r4  re   )ra  gantt_project_id_listr   process_parent_id_setr`  r  clean_cache_idsr  s           r1   _outline_force_recalcz"CmfGanttTask._outline_force_recalcD  s+     	8%5$6!!.&&tTlCnCnCn  @D&  E  EC$7$73$7$7$7!	ksShOiOikklll 5 D	J D	JGGjFVjjjkkk$'EE!!%%d+++' @J!6!:!:!<!<~JZ~~n|~~%L &)5==??GG&4(8N N   #&%% 6 6A*+ @-11!I,???#'')5555ABBB!001JDQ`LaLabbbHIIIA ( @J	D	J D	JrI   c                 J    t          t          j        j        d| i           d S )N
project_idre  )rm  r&   r   calc_critical_path_job)r  s    r1   r   zCmfGanttTask.calc_critical_path  s(    f1HR^`jQkllllllrI   r  u.   Расчет критического пути)rY  rZ  r[  r  r  c           
      L  	
 fd	fd
fdd	
f	d	t           j                            | dg          }|st          d|  d	d
           |j        j        }|                    |                                           |                    d
d
           t           j	        
                                \  }i t                      t          dg d          t                      |j        j        |j        j        <   t                      t                      g ddd|j        gg dg dg}d t           j                            |          D             t                                                    D ]} |           d S )Nc                 n    | vr)t           j                            dd| g          }|| <   |          S )Nra   rR   rS   )r&   r   r'   )r  r.   r"   gantt_tasks_by_ids     r1   _get_gantt_taskz<CmfGanttTask.calc_critical_path_job.<locals>._get_gantt_task  sH     $555#044T4<W`f4gg
3=!-0$]33rI   c                     | j         vrddd| j         gg dg dg}dg}t          j                            ||          }|st	          d| j          d	           |j        j        | j         <   | j                  S )
Nr  rR   )rr   rR   rP   r!   rR   Nr   rS   uW   Не найдена гант-задача у гант-проекта в проекте Tr   )r  r&   r   r'   r   r   r   )r.   r   _fieldsgantt_project_gtproject_end_datess       r1   _get_project_finish_datezECmfGanttTask.calc_critical_path_job.<locals>._get_project_finish_date  s    (,===!4)>?EEE***
 //#)#6#:#:'RY#:#Z#Z ' ]  P  yC  yN  P  P  X\  ]  ]  ]  ];K;];c!*"78$Z%:;;rI   c                     | j         vrM|                     ddg           | j        j        p!t          j                            ddg          | j         <   | j                  S r:  )r  r   r   r   r&   r   r'   )r.   calendars_by_project_ids    r1   r   z:CmfGanttTask.calc_critical_path_job.<locals>._get_calendar  s    (,CCC&&(:<W'XYYYAKASA\  Bc`f`r`v`v  }M  Wa  Vb`v  ac  ac'
(=>*:+@AArI   Fc                 `  	  |           }|j         j        v rd S |r||j         j        <   nI                    |j         j        d           }|s'|j        r                     |j        j        d           }d |_        d |_        d |j        _        d|_        |j	        r|j
        r|j        sH|j        j        s$|j        j        s|j        j        s|j        j        r|                    d           d S |sd}t                              d| d|j                    |j        r5|s3|j        j        vr%  |j        j                  |dz              d S |j         j        v rt#          dd	           n                    |j         j                   |}|j         j        v rg }|r|                    |           |j         j                 D ]\  }}  |          |dz              |v r]|         j        }	|r9t(          j                             |          |	t/          |           
          }	|                    |	           |rt1          |          }|j        j        s||_        t(          j                             |          |j        j        t/          |j                   
          |_        t(          j                             |          |j
        j        |j        j                  |_        |j        j        dk    |_        |                    d           |r||j         j        <   |j        j        r|j                            dg           d |j        j        D             }
d }d }d }d}|
D ]}  |          |d|dz                                  |d           }|s6|r|j        rt1          ||j                  n|j        }|r|j        rt;          ||j                  n|j        }|r|j        rt1          ||j                  n|j        }|s	|j        rd}||_        |j        rl|p
 |          |_        t(          j                             |          |j
        j        |j        j                  |_        |j        j        dk    |_        n||_        ||_        ||_        |                    d           |j        j        |j        j        |rt1           |          |          |_        n |          |_        t(          j                             |          |j        j        t/          |j                   
          |_        t(          j                             |          |j
        j        |j        j                  |_        |j        j        dk    |_        |                    d            |j        j        |j        j        |j        j        |j        j                  |j         j        <   d S )NFTr%  rX  zcalc_critical_path: level: z, )rl  u@   calc_critical_path: Обнаружен цикл в связях.r   )r   r   rJ  )r   r   r   r   zchild_tasks.op_gantt_taskc                 &    g | ]}|j         j        S rZ   )r\   r   )r^   r  s     r1   r`   zRCmfGanttTask.calc_critical_path_job.<locals>._calc_is_critical.<locals>.<listcomp>  s    *i*i*i1+=+C*i*i*irI   )late_start_datefrom_parent_taskrl  r$  late_finish_daterj  is_critical_path)ra   r   r'   r   r\   r$  r'  rj  r(  r   r   r   r   r+   r  r  r   r   ro  r2  r&   r   r   r   r   r   r   r   rE  r   r   )r  r$  r%  rl  r.   #following_tasks_min_late_start_datefollowing_late_start_datesfollowing_gantt_task_idr$  following_late_start_datechildren_gantt_task_idsmin_child_late_start_datemax_child_late_finish_datemin_child_total_slackhas_critical_path_childchild_gantt_task_iddone_child_taskCriticalPathValues_calc_is_criticalr   r  r  done_gantt_tasksgiven_late_start_date_by_gt_idtask_out_linksvisited_gantt_taskss                    r1   r5  z>CmfGanttTask.calc_critical_path_job.<locals>._calc_is_critical  ss   (77J}"&666 xFU.z}/BCC #A"D"DZ]EXZ^"_"_& x:+A x&D&H&HI_Iprv&w&wO)-J&*.J'+/J"(*/J'/ J4P U_Un .94!2=4 "-84 "2=	4 OOdO333 GGL%LL:?LLMMM &( *;CVVV!!//*2H2Y"Z"Zbgjkbkllll}"&999]eijjjjj#''
(;<<<2A/}"n44-/*" G.55oFFF>LZ]M`>a U U:+]%%oo6M&N&NV[^_V_````.2BBB4DE\4]4m1( 8>8J8_8_)6z)B)B(A*-m*<*<)< 9` 9 95
 399:STTT- 8:=>X:Y:Y7%?: 86Y
35;5G5\5\%2]:%>%>$.$?$E&)**C&D&D%D 6] 6 6
2
 281C1X1X%2]:%>%>$.$@$F","="C 2Y 2 2
.
 7A6L6RVW6W
3"$7772 jFi.z}/BC. )0++-H,IJJJ*i*iZ_Mh*i*i*i',0)-1*(,%*/'+B 7 7'%%oo6I&J&J6Y7;,1AI7 7 7 7 '7&:&:;NPT&U&UO* !  51~9H9X1~4MOn0o0o0o^m^} . 62A:I:Z2A5OQ`Qq1r1r1r`o  aA / 1-r5D5P-rC0EGb,c,c,cVeVq *2 77W 726/-F
*' J2U2}YqYqr|Y}Y}J/-3-?-T-T!.z!:!: * < B(9? .U . .J*
 3=2H2NRS2SJ//2LJ/-BJ*2IJ/$///*08J<W<]<e" W256N6Nz6Z6Z\k2l2lJ//2J2J:2V2VJ/-3-?-T-T*]:66&7=!*";<<< .U . .
*
 *0);)P)P*]:66&8>$5; *Q * *
&
 /9.D.Ja.O
+$///4F4F * : @!+!<!B&28!+!<!B	5 5 5Z]0111rI    main_gantt_project.op_gantt_taskr^  u   Проект с id "u   " не найден.Tr   )r_  r`  r4  r&  )	r   r   r   r   rs   rq   r   r$  r'  r   rR   )rr   r=  rP   r  c                 (    i | ]}|j         j        |S rZ   )ra   r   )r^   r.   s     r1   ru  z7CmfGanttTask.calc_critical_path_job.<locals>.<dictcomp>q  s1      H  H  HZ]0*  H  H  HrI   rS   )NFN)r&   r3  r'   r   main_gantt_projectr/   r   rc   ra  rf   get_start_finish_graphsrn  r   dictr   r   r  r   re   rx  )r  r   gantt_project_gantt_taskr]  r   r  r4  r5  r   r  r  r!  r6  r"   r  r7  r  r8  r9  s         @@@@@@@@@@@@@r1   r  z#CmfGanttTask.calc_critical_path_job  s   
	4 	4 	4 	4 	4 	4	< 	< 	< 	< 	<	B 	B 	B 	B 	B]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	~ #'':?a>b'cc 	[MZMMMUYZZZZ#*#=#K  ,,-E-Y-Y-[-[\\\ @@$bf@ggg"4LLNN!ee'(<  ?I  ?I  ?I  J  J FFG_GqGw2=CD"&&&)-&c c c 6AB==="""

 H  HvObOgOgov  @FOg  PG  PG  H  H  H !2!7!7!9!9:: 	- 	-Mm,,,,	- 	-rI   u*   Пересчет гант проектовc                 ^   g }| rdd| g}t           j                            dg|          D ]}|j        }|sd|j        _        d|j        _        d|j        _        d|j        _        dd|gdd|gg dd	g d
g dgg dg dgg dg dgg dg dggg}g d}d}	 t           j	                            ||dz   g||dg          }|sn|D ]}|j        xj        |j        j
        pdz  c_        |j        xj        |j        j
        pdz  c_        |j        xj        |j        j
        pdz  c_        |j        xj        |j        j
        pdz  c_        |dz  }|j        j        |j        _        |j        j        |j        _        |j                            d           t                       d S )Nr   rR   r:  )r"   rT   r   r2  rP   )rt   rR   Nrg  )r  r=  N)r  r=  r   )r   r=  N)r   r=  r   )r  r=  N)r  r=  r   )r   r=  N)r   r=  r   )r  r   r  r   T  cmf_created_at)slicerT   r"   r  r%  )r&   r3  re   r<  r/   r  r  r  r  r   r   r   r   r+   r  )	project_codeproject_filterr   r   rT   r"   r  rv  r.   s	            r1   recalc_gantt_projectsz"CmfGanttTask.recalc_gantt_projectsv  s~     	8"D,7N(--6X5Ybp-qq B	 B	G#6M   78M'378M'467M'378M'4 g.%t];000333000
 322///
 433000
 322///	F0  F A$166a4[>D>DAQ@R 7 T T # "- a aJ!/;;z?U?[?`_``;;!/<<
@U@[@`_``<<!/;;z?U?[?`_``;;!/<<
@U@[@`_``<<<T	!$ 6C5P5]M'25B5P5]M'2',,t,<<<LLLLEB	 B	rI   c                 X  	 	fd}t          t                    	g d| gg d |            }g d}dg}t          d t          j                            |d|          D                       }d	d
|g |            }|                    |           |rdd
|g |            }|	S )Nc                     t                      } d}d}	 t          j                            |||z   gd          }|sn|D ]}|j        s2|j        r+|j        j                                     |j                   ;|j        rU|j	        j
        sI|                     |j	        j                   |j	        j                                     |j                   ||z  }| S )NrA  r   T)rT   r"   rC  include_archived)rn  r&   r  rg   r`  ra  r   r\   ro  r   cmf_deleted)
parent_idslimitsteptasksr   r  r   trees        r1   update_treez0CmfGanttTask.get_gantt_tree.<locals>.update_tree  s   JED,,"".%)	 -    ! [ [D. [43H [T/@AEEdF[\\\\, [T5E5Q ["t'7'HIIIT->?CCDDYZZZ%( rI   )r   rR   F)zparent_task.op_gantt_task_idzgantt_project.op_gantt_task_idr\   zparent_task.cmf_deleted)r  rR   factr  c                 ^    h | ]*}|j         	|j                             d           #|j         +S )r  )r  
startswith)r^   r  s     r1   r^  z.CmfGanttTask.get_gantt_tree.<locals>.<setcomp>  sQ     'a 'a 'a*--'a<?M<T<TU^<_<_'as} 'a 'a 'arI   T)rT   rI  r"   ra   rb   r\   )r   rn  re   r&   r  rg   r  )
leaf_filterrP  parent_ids_set
tth_filter
tth_fieldstask_ids_from_tth_factparent_ids_set_from_tthr  r   rO  s
          @@@r1   get_gantt_treezCmfGanttTask.get_gantt_tree  s0   	 	 	 	 	 	 	6 3333[A D  D  D$333
!]
!% 'a 'a*0*F*L*LT^qu  I*L  +J  +J'a 'a 'a "b "b 56"-+--5666 	+)4@G([]]N  	+ rI   c                  j	   fdddg dg dgg dg dgg dg dgg d	g d
ggdg dg dgg dg dgg dg dgg dg dggg} t          d           t          j                            |           t	          d           t          j        j        }t          j        j        }t          j        j        j	        
                                }t                                                    }d                                 D             }||z
  }t          ||z            }|                    |j        t#          j        |j                                                ||j        |j        k                                  t1          |j                            |          |j        dk    |j        dk                                            |j                                                  }d |D             }	d}
t=          dt?          |          |
          D ]}||||
z            }g d}t          j                             dd|g|d           }|D ]}|j        |j                 d!<   |j!        pd|j                 d"<   |j"        ptG          d#          |j                 d$<   |	$                    |j        d          |j                 d%<   |j%        ptG          d#          |j                 d&<   |j&        pd|j                 d'<   |j'        ptG          d#          |j                 d(<   ېd}|D ]Q} |           |d)z  }|d*z  dk    s|t?          |          k    r#t          d+| d,t?          |           d-           Rr|(                    |j)        *                                +                    |j        tY          d!          k                                  tY          d"          tY          d$          tY          d'          tY          d(          tY          d.          tY          d/          0          t                                                               t[                       t\          /                                 t          d1           d3S t          d2           d3S )4u   
        Пересчитывает 'actual_work', 'actual_cost', 'sched_work', 'sched_cost' от детей к родителям
        c                 $   | |          d<   | vr|          d         |          d<   |          S d|          d<   d|          d<   d|          d<   d|          d<   |          }|D ]}} |          }|          dxx         |d         z  cc<   |          dxx         |d	         z  cc<   |          dxx         |d         z  cc<   |          dxx         |d         z  cc<   ~|          dxx         |          d         z  cc<   |          dxx         |          d
         z  cc<   t          |          d         |          d                   |          d<   t          |          d         |          d	                   |          d	<   |          S )Nr  r  r  r   r  r  r  r   r   r  )r   )node_idchildrenchild_id
child_datacalculate_node	node_datarO  s       r1   ra  z6CmfGanttTask.recalc_gantt_tree.<locals>.calculate_node  s	   29Ig/ d""4=g4FG[4\	'"=1 ))12Ig~.12Ig~.01Ig}-01Ig}- G}H$ O O+^H55
'">222j6NN222'">222j6NN222'"=111Z5NN111'"=111Z5NN1111g}---71CDX1YY---g}---71CDX1YY---/29W3En3UW`ahWijvWw/x/xIg|,/29W3En3UW`ahWijvWw/x/xIg|,W%%rI   rg  )op_gantt_task.actual_workr=  N)rc  r=  r   )op_gantt_task.sched_workr=  N)rd  r=  r   )op_gantt_task.actual_costr=  N)re  r=  r   )op_gantt_task.sched_costr=  N)rf  r=  r   )%parent_task.op_gantt_task.actual_workr=  N)rg  r=  r   )$parent_task.op_gantt_task.sched_workr=  N)rh  r=  r   )%parent_task.op_gantt_task.actual_costr=  N)ri  r=  r   )$parent_task.op_gantt_task.sched_costr=  N)rj  r=  r   u(   Получаем дерево задач)rT  c                      dddddddS )Nr   )r  r   r  r   r  r  rZ   rZ   rI   r1   <lambda>z0CmfGanttTask.recalc_gantt_tree.<locals>.<lambda>E  s(    [\lm  @A  ST  )U  )U rI   c                     h | ]	}|D ]}|
S rZ   rZ   )r^   r^  childs      r1   r^  z1CmfGanttTask.recalc_gantt_tree.<locals>.<setcomp>L  s%    QQQQQuuQQQQrI   rQ  Fc                     i | ]
\  }}||pd S )r   rZ   )r^   tidss      r1   ru  z2CmfGanttTask.recalc_gantt_tree.<locals>.<dictcomp>`  s"    888VS!3a888rI   rA  r   )r  r  r  r   r   r  r  ra   rb   T)rT   r"   r  r  r  0r  r  r  r   r   rX  
   u   Обработано u    из u    ветокr  r  )r  r  r   r   r  r  u:   Обновленные данные внесены в БДu/   Нет данных для обновленияN)0printr&   r   rZ  r   dp_modelr  r  r  r  r  rn  rx  r  re   queryra   r
   r  r  joinr1  r  rT   r   in_r  rJ  group_byallranger  rg   r  r  r~   r'   r  r   r   r  	__table__r  wherer	   r  r  flushdb)rT  	GanttTaskTimeTrackerHistorysessionparent_nodeschild_nodes
root_nodes	all_nodestth_rowstth_sum
batch_sizer  	batch_idsr"   rv  r.   progress_countrootra  rb  rO  s                     @@@r1   recalc_gantt_treezCmfGanttTask.recalc_gantt_tree  se    	&  	&  	&  	&  	&  	&  	&D ===:::
 =<<999
 >==:::
 =<<999$ IIIFFF
 IHHEEE
 JIIFFF
 IHHEEE'%
L 	8999"11k1JJ  !U  !U  V  V	'0	#9B.#/7799499;;''QQT[[]]QQQ!K/
|344	 U9<*<*G!H!HIIT$i&7;M;W&WXXVL$$Y//&3v=&2e;   Xil##SUU 	 98x888
q#i..*55 	_ 	_A!!A
N"23IF -33D$	;R[asw3xxK) _ _
<FM	*-(9:D:P:UTU	*-(7:D:P:`T[\_T`T`	*-(7AHZ]\]A^A^	*-()=>AKA^Anbijmbnbn	*-()=>9C9N9SRS	*-(69C9N9^RYZ]R^R^	*-(66_  	b 	bDN4   aN"a''>S__+L+L`n``C
OO```aaa  	EOO#**,,y|y'A'AABB )- 8 8 )- 8 8(66(66!*>!:!:!*>!:!:    Y%%''((   LLLNOOOOOCDDDDDrI   rK   )NF)FFF)F)NFNF)FFFFF)FF)FFFF)NN)FFNFr   r   )r  )y__name__
__module____qualname__	api_allowr   api_methodsclassmethodr2   r9   r7   r8   rN   ro   rc   propertyr   r   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r  r!  r.  r8  r   rB  r'  rQ  rS  rW  staticmethodcmf_deferred_jobrc  ra  r{  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rN  r(  r*  r-  r0  r7  r  r>  rE  rG  rI  rK  rM  rO  r  r  r  r  rX  r	  rf  r(   r5  ry  rD  r+   r  r  r  r  r  r  r  rC  ro  r  r   r  r  r  r  r   r  rF  rZ  r  __classcell__)rw   s   @r1   r   r      sY
       I*.DFZ-[[K  [&    [86 6 6 - - -
4 4 4 46dW\ ! ! ! !B4 4 4 4 42 I I XI   X   X   X6   X*$ $ $ $L$ $ $ $N)9 )9 )9V]9 ]9 ]9~, , ,b b b bB% % %       2! ! ! !*!O !O !O !OJ  (@ @ @*B7 B7 B7 B7H]" ]" ]"~" " ":^ ^ ^5? 5? 5?n> > >2> > >$7 7 7n n n i[1MMM" " NM \" Z# Z# Z# Z#xJ J J J4S S S,L L L2E" E" E"N ejY^:?5? 5? 5? 5?n# # #!\ !\ !\ !\F9 9 90   K K K K* * * _dV[;7 ;7 ;7 ;7zI I I.) ) )) ) )  ( ( (; ; ;8 8 8- - -. . ./ / / /</ / / /&? ? ?C C C* * *`6 `6 `6 `6D "w  NR $o5FQRT T T3s 3s 3sT T \3sj5$ 5$ 5$ 5$ncE cE cE cEJ7 7 7" " "" " " "6" " "& & & % % %% % %NK K K0" " "
  " " "& & &" " "' ' '
' ' '
I I I47 7 7(C C C C  "& & &4! ! !:LG LG LG LG\&# &# &# &#P   & &*uV[ - - - - - - -^. . . . . .3U R R R R R R R2    1 1 1 1 11 1 1 1 1C C C C4' ' 'B2^ 2^ 2^x '  '  'D\ \ \>EQ EQ EQ EQN$y $y $yL Z Z Z [Z
 "}  IJ  K  K  K12 12 K  K \12f "fqrsssKJ KJ KJ ts \KJ\ m m \m l^a*.<ln n nY- Y-n n \Y-v "NYZ[[[G G G \[ \GR 1 1 1 \1f VE VE \VE VE VE VE VErI   r   )r   r   dateutil.tzr   decimalr   r   r   collectionsr   r   
sqlalchemyr	   r
   r   r  
cmf.fieldscmf.include#modules.gantt.fields.cmf_gantt_taskr   rZ   rI   r1   <module>r     s              7 7 7 7 7 7 7 7 7 7 / / / / / / / / , , , , , , , , , ,          < < < < < <~5E ~5E ~5E ~5E ~5E< ~5E ~5E ~5E ~5E ~5ErI   