
    @i4                        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                       e Zd ZdZej        g d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$dd"Z%dd#Z&d$ Z'd% Z(e) e*dd&gd'(          d)                         Z+dd*Z,dd+Z-d, Z.d- Z/d. Z0	 	 	 dd/Z1d0 Z2dd1Z3d2 Z4d3 Z5dd4Z6d5 Z7	 	 dd6Z8d7 Z9d8 Z:d9 Z;d: Z<d; Z=d< Z>d= Z?d> Z@d? ZAdd@ZBddAZCdB ZDdC ZEdD ZFddEZGe) e*dFdddGgd'H          ddI                        ZHddJZIddKZJdL ZKdM ZLddNZMdO ZNdP ZOdQ ZPdR ZQdS ZRdT ZSdU ZTdV ZUdW ZVdX ZWdY ZXdZ ZYd[ ZZd\ Z[dd]Z\d^ Z]d_ Z^d` Z_ddbZ`ddcZadddZbdd	d	de fdf
Zc fdgZdd	d	dh fdi
Ze fdjZf fdkZg fdlZhddnZido Zje)dp             Zkdq Zldr Zmds Zne) e*dd&dtgd'duv          dw                         Zodx Zpdy ZqddzZrd{ Zsedd|            Zte) e*d}d'~          d                         Zue) e*dd'~          dd                        Zve)d             Zwe) e*ddgd'dd          d                         Zxe) e*dd'~          dd                        Zye)dd            Zze)d             Z{e) e*ddgd'(          d                         Z| xZ}S )r   T)outline_insert_aftercalc_critical_path&force_pass_actual_dates_to_sched_datesc                    t                                           }g d}t           j                            d ||          }|r%|D ]}||         ||<   d|_        d|_        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   fieldsr   FT)emitnotify	only_data)modelsr   getstart_variancefinish_varianceduration_variancer"   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   s7   ((**
T T T +//t$v/VV 	- 9 9$1%$8
5!!()J%)*J&+,J($
%%'''##%% 	F 	FOOuOEEE	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	Fs   C  CCNc                 T   t                                           }|r|                     ||          S |j                                         |j        |_        ||_        |j        |_        |j        |_        |                                 |	                                 |j
        |_
        |j        r/|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   r6   r   loadr   	cmf_owner
cmf_author
_calc_type_calc_projectr   r   !gantt_sync_actual_and_sched_datesupdate_sched_dates_from_actualr-   r.   r/   )r0   r   r1   r2   s       r5   create_gantt_taskzCmfGanttTask.create_gantt_task*   sW   ((**
 	G66tXFFF 	!!!#'#5
 
  $~
 $
 	  """!%!1
 	m@EEGGG8B8J8lJ5##%% 	6 	6OOuO555	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6s   9DD!$D!c                    | j         rz| j         j        rnt                              | 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   
project_idAPPget_cache_projectdefault_gantt_task_typetask_sched_type)selfdefault_types     r5   r;   zCmfGanttTask._calc_typeK   s    9 	6- 	6001EFF^L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   rP   s    r5   r<   zCmfGanttTask._calc_project[   s<    9 	-* 	-9,DLLL	- 	- 	- 	-rR   c                 R    | j         r| j         j        S | j        r| j        j        S d S rT   )r   r3   r   rU   s    r5   _get_parent_gantt_taskz#CmfGanttTask._get_parent_gantt_task`   s:     	2#11 	4%33	4 	4rR   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   r[   r"   filterr#   r   relation_type.coder[   system.additional_parentin_linkzout_link.op_gantt_task_idc                 &    g | ]}|j         j        S  )out_linkop_gantt_task_id.0rels     r5   
<listcomp>z:CmfGanttTask._get_children_gantt_tasks.<locals>.<listcomp>   s    ,w,w,wsS\-J,w,w,wrR   idIN)
save_preload_fieldsr   logic_prefixr'   r   listr"   CmfRelationOptionslistextend)rP   
add_filterr#   include_additionalchild_gantt_tasks additional_child_tasks_relationsadditional_gantt_task_idsadditional_gantt_taskss           r5   _get_children_gantt_tasksz&CmfGanttTask._get_children_gantt_tasksf   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&!(()?@@@  rR   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_datetask.responsibleztask.responsible.calendarz"task.responsible.calendar.timezoneztask.executorstask.parent_taskztask.is_milestone task.gantt_project.op_gantt_task)superrl   )rP   r#   	__class__s     r5   rl   z CmfGanttTask.save_preload_fields   s1    
 
 
. ww**,,V33rR   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   rP   ress     r5   _perform_costzCmfGanttTask._perform_cost   sM    ?" 	4o 66<s||$$WV__x$HHHrR   c                     | j         j        rd S | j         | j        z  dz  }t          |                              t          d          t
                    }t          |          S Nr   1r   )r   r   r   r   r   r   intr   s     r5   _perform_durationzCmfGanttTask._perform_duration   sY    & 	4!D$::S@cll##GCLL8#DD3xxrR   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     r5   _perform_workzCmfGanttTask._perform_work   sW    ?" 	4o 66<cll##GCLL8#DD3xxrR   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   secondsr   r   r   )r   r   r   _get_calendardttimezone	timedeltar   datetimenowget_work_timedeltavaluer   r   r   )rP   calendartzr   delta_finish_time_secdelta_now_time_secperform_completer   s           r5   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rR   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 )	NTrY   rZ   r   r[   r"   r]   F)r   has_child_tasksrm   r"   r'   r   sget)rP   _filterhas_childrens      r5   r   zCmfGanttTask.has_child_tasks   s~     9$ 	49!%999 ,++ $	24-G
 ".3373CCL turR   c                    |sd S d}|}|r|S | 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   rC   r   r   r   r   namecode	cmf_alert	rP   estimated_datereturn_correct_datefrom_actualalertcorrect_datetext
constraintconstrain_dates	            r5   check_correct_start_datez%CmfGanttTask.check_correct_start_date   s    	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$''''rR   c                    |sd S d}|}|rd}| j         dk    r| j        r|sd}d}n{| j        rtd}| j        j        }| j        dk    r||k    r|r||k     r
d}|}d|d}n9| j        dk    r||k    r|sd}|}d	|d}n| j        d
k    r||k     r
d}|}d|d}d| d|d}|r7|s5|rd}d| j        j         d| j        j         d| d}t          |d           |S )NFr   Tu   невозможно изменить дату окончания, если зафиксированы дата начала и длительностьr   .   Фиксированное окончание r   1-after%   Окончание не раньше 2-before#   Окончание не позже r   uK   " конфликтует с плановой датой окончания u   Данное действие невозможно, обратитесь в проектный офис или к постановщику задачиr   r   r   r   r   )	r   rC   r   r   r   r   r   r   r   r   s	            r5   check_correct_finish_datez&CmfGanttTask.check_correct_finish_date  s    	F% 	("'$	11d6I1R]1E nDD' 	eJ!7=N)Y66>^;[;[" ln~&E&E E#1L!kR`!k!k!kJ+y88^n=\=\ep=\-^^^^^

+z99n~>]>]-\>\\\
dz d dJXcd dD  	(, 	( q q~RVR[R`~~eienes~~w{~~~Dd$''''rR   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)
        NNNrY   r   r   r   r   N)rW   r   rm   load_fieldsrl   get_parent_plan_limitr   r   maxr   r   minrC   r   )rP   parent_start_limitparent_finish_limitparent_duration_limitparent_gantt_taskstart_limitfinish_limitduration_limits           r5   r   z"CmfGanttTask.get_parent_plan_limitD  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8rR   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   rx   r   r   r   r   r   r   r   r'   CmfCalendarget_date_by_durationr   r   r   rC   get_childrens_plan_limit)
rP   r   r   r   r2   r   r   ch_start_limitch_finish_limitch_duration_limits
             r5   r   z%CmfGanttTask.get_childrens_plan_limito  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8rR   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_minrU   s    r5   _calc_plan_limits_cachez$CmfGanttTask._calc_plan_limits_cache  st    47?? 	F,0)&&(( 	_"D$?A^ ))++ 	_"D$?A^A^A^rR   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)rP   r   r   r   calendar_durations        r5   _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rR   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   rU   s    r5   _calc_actual_durationz"CmfGanttTask._calc_actual_duration  s    ! 	%d&= 	%#)#5#J#J""$$d&<&BDD[Da$c $cD   #' 	%D,C,G 	%#$D   	% 	% 	% 	%rR   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   r   )rP   rollbackr   r   r   s        r5   _calc_sched_start_datez#CmfGanttTask._calc_sched_start_date  s      +@@  $"8">TEXAYAY@Y[ [  88MUEP 9 R R &)33. 4373MP`3`3`#9rR   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   )rP   r  r   r   r   s        r5   _calc_sched_finish_datez$CmfGanttTask._calc_sched_finish_date  sq      +@@  $"7"=s4CV?W?WY Y !::.OWGR ; T T ! rR   c                    | j         j        s| j         dk    r=| j        j        sd | _        n'| j        r| j        | _        n| j        r| j        | _        d S | j        j        r| j        j        rd S | j        r/| j        s(|                     ||          | _        |rd | _        nd S | j        rJ| j        sC|                     |          | _        | j        dk    r|                     |          | _        d S | j	        dk    r>| j        dk    r5| j
        r0t          d| j        j         d| j        j         d           d S d S d S d S )	Nr   r  r   r   r   r      В задаче "r   u   ) плановый период может не соответствовать плановой длительности, т.к. все переменные зафиксированы)r   r   r   is_milestoner   r   r  r  r   r   rC   r   r   r   )rP   r  r   s      r5   _calc_sched_periodzCmfGanttTask._calc_sched_period2  s   & 	$*=*B*B9) C)-&&( C-1-BD**+ C,0,BD)F ( 	T-C-K 	F  	)? 	%)%A%A8al%A%m%mD" (,%% ! 	$*? 	$($?$?K$?$X$XD!)Y66)-)E)ER])E)^)^&F $	11d6PT]6]6]bfbu6]  E$).  E  ETY^  E  E  E  F  F  F  F  F 216]6]6]6]rR   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   rU   s    r5   _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	 	rR   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   r   5-timetrackerN)actual_complete_typeactual_workis_not_nullr   mathfloorr   actual_completer   $notify_parent_update_actual_completetimetracker_sched_work)rP   tmp_completes     r5   _calc_actual_completez"CmfGanttTask._calc_actual_completeq  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3VrR   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_pointsrY   rZ   r   r[   agile_story_pointszstatus.status_typer\   r   =CLOSEDr   3-costz4-fixed)r   r  rx   lenrj   r  r   r   rm   r'   CmfTaskrn   r   r  statusstatus_type)
rP   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
             r5   _calc_summarry_actual_completez+CmfGanttTask._calc_summarry_actual_complete  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5rR   c                 P   |                                   | 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        rC| j        r<| j        | j        k    r,t/          d
| j        j         d| j        j         dd           | j        rC| j        r<| j        | j        k     r,t/          d
| j        j         d| j        j         dd           | j        dk    | _        | j        r | j        j        r|                                  |                     d           d S )N)r   r   r   r   r   r   1-earlyra   r[   )z(out_link.op_gantt_task.sched_finish_dateconstrain_lagz"out_link.project.calendar.timezoner\   r	  r   u   ) нельзя указать Дату начала больше зафиксированной у дочерней задачи.Tr   u   ) нельзя указать Дату начала меньше зафиксированной у родительской задачи.r&   )r   r   r   r   r   r   r   r   r'   ro   rn   r   rd   r3   r   r   r2  r   r   r   r   rW   r8   r   r   r   lock_sched_start_dater   _do_sched_start_date_is_changedr/   )
rP   r   in_relationsmax_prev_dater   in_relationfinish_datenew_sched_start_dater   parent_sched_start_dates
             r5   #_do_constrain_start_date_is_changedz0CmfGanttTask._do_constrain_start_date_is_changed  s3   $$&&&$(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%% 	\$*? 	\DDY\`\vDvDv  O$).  O  OTY^  O  O  O  W[  \  \  \  \% 	d$*? 	dDDY\`\vDvDv  W$).  W  WTY^  W  W  W  _c  d  d  d  d0 &*%>)%K"  	3T%:%E 	300222		D	!!!!!rR   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 )NrY   rd   r  )r_   r  r`   ra   r\   c                 0    g | ]}|j         j        j        S rc   )ra   r   rj   rf   s     r5   ri   z8CmfGanttTask._get_parent_gantt_tasks.<locals>.<listcomp>;  s     +i+i+iSCK,=,@+i+i+irR   r"   task_idrk   )r   rm   rW   r   rl   appendr'   ro   rn   r"   r   rq   )rP   parent_gantt_tasksr   r   additional_parents_relationsadditional_parents_tasks_idsadditional_parents_filteradditional_parentss           r5   _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!!rR   c                     | j         j        r"| j         j        j        r| j         j        j        S | j        r$t                              | j                  j        S t          j                            ddg          S )Nsystem:defaultr   r   r#   )	r   responsibler   rK   rL   rM   r'   r   r(   rU   s    r5   r   zCmfGanttTask._get_calendarF  so    9  	2TY%:%C 	29(11? 	C((99BB!%%+;ZL%QQQrR   c                    d }d }g d}|                      |d          }|D ]]}|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                  }|                     |           |                     |           _| j        r+| j        r$| j        rd | _        | 
                                 d S |r|| _        |r|| _        |                     d           d S )	N)r   !=TTrr   rs   r   r   r  r3  r   )r   )rx   r   r   r   r   r   newr   r   "_calc_sched_period_for_child_tasksr  calc_variance_alert_changed_plan_fields_check_start_finish_relationsr/   r   r   r   r   r   r   r   )rP   r   r   rr   child_tasks
child_tasks         r5   rR  z/CmfGanttTask._calc_sched_period_for_child_tasksO  s3    ...
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%  ;):&%%%>>>>>rR   c           	      :   |                      | 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 )Nr   r   u/   Предупреждение: В задаче "r   u2   ) дата начала перемещена на r   ub   , так как была позже даты ограничения дочерней задачи.Tr  
start_dater   durationchanged_field)r   r   rQ  r   r   r   r   r   r   r   rR  r   lock_sched_finish_dater   r  r   _calc_resourcesrP   r   r^  s      r5   r5  z,CmfGanttTask._do_sched_start_date_is_changed  so   %%T5J5N\g%hhh$$&&& 	>D$9$= 	>) @d.H4K`.`.`(,(B% DIN  _c_h_m  NRNht   @ @ @ 3355555 M" +t'< +TE` +)-&'';'OOO ,))4)HHH *  } =====rR   c                    |                      | j        j        |           |                                  d }| j        rN| j        sG|                     |           d}| j        r'| j        j        r| j        r| 	                                 n| 
                    d           d}| j        s|                     |           d S d S )NrY  r  rZ  Tr[  r\  r]  )r   r   rQ  r   r   r   r  r   r   rR  r   r`  ra  s      r5    _do_sched_finish_date_is_changedz-CmfGanttTask._do_sched_finish_date_is_changed  s    &&d6L6P^i&jjj$$&&& 	't'< 	'###<<<(M# :(=(H :TMb :77999%%t%DDD&M# 	>  } =====	> 	>rR   c                    |                      | j        j                   |                     | j        j                   |                     d           | j        r|                                  |                     d           d S )NrP  Tr[  r\  r]  )	r   r   rQ  r   r   r   r   rR  r`  rU   s    r5   _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6rR   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   )rP   rW  msgs      r5   %_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IrR   r?     )	only_onceonly_once_argspriorityc                 F   t           j                            |           }|sd S |                                }|                    |           t           j                            ||          }|sd}|                    d||           |                    d           d S )Nrj   rj   r#   T)deferredrW  ignore_child_taskr3  )r'   r   r(   rl   r   from_sched_dates_of_child_tasksr/   )r?  child_task_idrr  r   r#   rW  s         r5   #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	!!!!!rR   c                 d   |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| j         j
         d| j         j         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            |                                  |                                 }|rt0                                          5  |D ]}|                    |                                            |                    | |!           |                                 |                                 |                    d"d#           	 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
                игнорировать дочернюю задачу при обновлении дат родительской задачи.
        rY   )r?  rt  rr  kwargsNr	  r   u   ) невозможно обновить даты из-за обнаруженного цикла обновления дат задач связями Дополнительный родитель/Дополнительная дочерняя задача.Tr   ORr   rL  N)r   rL  NrM  ")r   r   r   r   r   r   r   r   r   r   r   r   uU   Конфликт планирования: В родительской задаче "u   ) ограничение "u<   " конфликтует с дочерней задачей r   )r   r   )pathF
user_inputr&   )!r   rm   schedule_deferred_jobru  rj   r   r   ri  setr   r   r   addrx   r   r   r   r   r   r   r   r   rU  rF  r-   disable_aclr   rl   rs  rS  rT  r/   remove)rP   rW  rr  r}  rq  min_start_datemax_finish_dateschild_task_with_min_startchild_task_with_max_finishrr   gantt_tasksr2   r   conflict_child_task_min_startr   conflict_child_task_max_finishr   conflict_child_taskrA  r   s                       r5   rs  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$). B BTY^ B B 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 	**,,, "99;; 
	M$$&& 	M 	M); M M%%11$2J2J2L2LMMM%EE! F    &33555%@@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   6BPP
P
c                    |                                  }|rt                                          5  t                      }|                    | j        j                   |D ]g}|j        j        |vrW|                    | ||           |                                 |	                                 |
                    dd           h	 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
                игнорировать дочернюю задачу при обновлении дат родительской задачи.
        )rr  r}  FTr~  N)rF  r-   r  r  r  rj   r   rs  rS  rT  r/   )rP   rr  rA  r}  r2   s        r5   update_parent_task_sched_datesz+CmfGanttTask.update_parent_task_sched_datess  s_    "99;; 	J$$&& J Juu'''"4 	J 	JJ!}*$66"BB .?!% C   
 #00222"==???"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)rF  r   r   r/   _change_parent_start_date)rP   r  parentsr   s       r5   r  z&CmfGanttTask._change_parent_start_date  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rR   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   Предупреждение: Плановая дата окончания дочерней задачи больше плановой даты окончания родительской задачи)rF  r   r   r   r/   _change_parent_finish_dater   r4  )rP   r  r  r   
date_values        r5   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"""rR   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        r| j
        r<| j        | j
        k    r,t          d| j        j         d| j        j         dd	           | j        r<| j        | j        k     r,t          d| j        j         d| j        j         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   r	  r   u   ) нельзя указать Дату окончания больше зафиксированной у родительской задачиTr   u   ) нельзя указать Дату окончания меньше зафиксированной у дочерней задачиr3  )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r_  r   r   r   r   rc  r5  r/   )rP   r   s     r5   $_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%! 	e* mt/EHc/c/c  `din  `  `  `  `  `  hl  m  m  m  m* et/EHc/c/c  Xdin  X  X  X  X  X  `d  e  e  e  e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	!!!!!rR   c                 P   | o#| j         j        o| j         dk    o| j        j         }| o| j         j         o| j         o| j        j        }|o| j        j         o| j        | j        k    }|s|s|r2| j        j         | j        _        | j                            d           | j        dk    r~| j        dk    rs| j	        j
        sg| j        j
        s[|r-t          d| j        j         d| j        j         dd           n,t          d| j        j         d| j        j         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   Tr3  r   u;   Конфликт планирования в задаче "r   u   ): невозможно изменить трудозатраты, если установлена опция "Фиксированные Ресурсы" и зафиксированы даты начала и окончания.r   u   ): невозможно изменить длительность, если зафиксированы даты начала и окончания.ua   Невозможно изменить плановую длительность, у задачи  (uZ   ) установлена опция "Фиксированная длительность".rO  r\  r]  )r   r   r   r
  r   r   r/   r   r   r   r   r   r   r   r   rC   r  r`  )	rP   from_sched_work_changedr   r   r   from_calc_resourcescase_acase_bcase_cs	            r5   r   z*CmfGanttTask._do_sched_duration_is_changed  s    .-  F$2E2I  FdNaefNf  Fosox  pF  lF--  Ad6I6M2M  ARVRe  Ajnjs  kA)|$)2H.H|TMcgkg|M| 	+V 	+v 	+)-)?%?DI"INNTN*** %22t7QU^7^7^1< 8_EIE_Ej 8_& { X\XaXf  koktky    $& & & & &  nX\XaXf n nkoktky n n nuy{ { { {  	 rz~  {D  {I r r  MQ  MV  M[ r r ry}   $ # 	?+ 7( 2-1D*'''666  , ?4K ?$$:$>>>>>+	? 	?(? ? ? ?rR   c                 .    |                                   d S rT   )r  rU   s    r5   _do_actual_duration_is_changedz+CmfGanttTask._do_actual_duration_is_changedJ  s      """""rR   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   rY   z"_do_actual_work_is_changed gt_id: z, gt.actual_work.new: z, gt.actual_work.old: z, work_delta: from_add_childr3  )gdebugrj   r   r   r   r  r   r   r   r   rm   actual_myself_workr  rQ  r   rW   r-   r  r   rl   from_child_add_work_do_actual_work_is_changedr/   r   r'   CmfTimeTracker"_op_gantt_actual_work_changed_hook)rP   from_timetrackerr  r   
work_deltar   s         r5   r  z'CmfGanttTask._do_actual_work_is_changedM  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                 Z   | j         j        rd S | j         dk     r,t          d| j        j         d| j        j         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   r	  r   ug   ) "Фактические Затраты" стал ниже нуля, выставляем в ноль.Tr   r!  r   rY   Fr  )actual_costr   r   r   r   r   r  r   r  r  r  r   r  r  rW   rm   rQ  r   r-   r  r   rl   from_child_add_costr/   )rP   r  
cost_deltar   s       r5   _do_actual_cost_is_changedz'CmfGanttTask._do_actual_cost_is_changedp  s(   # 	Fa  u$).  u  uTY^  u  u  u  }A  B  B  B  B$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  rU   s    r5   _do_actual_complete_is_changedz+CmfGanttTask._do_actual_complete_is_changed  sE    ' 	F$00F &(22F 32rR   c                     | j         j        pd| j         j        pdz
  }| j        s| j         | _        n| xj        |z  c_        |                     |           d S )Nr   r  )r  rQ  r   r   r  r  )rP   r  r  s      r5   !_do_actual_myself_work_is_changedz.CmfGanttTask._do_actual_myself_work_is_changed  sp    -16Q4;R;V;[Z[\
# 	+  $6D
*''9I'JJJJJrR   c                     | j         j        pd| j         j        pdz
  }| j        s| j         | _        n| xj        |z  c_        |                                  d S r   )actual_myself_costrQ  r   r   r  r  rP   r  s     r5   !_do_actual_myself_cost_is_changedz.CmfGanttTask._do_actual_myself_cost_is_changed  sj    -16Q4;R;V;[Z[\
# 	+  $6D
*'')))))rR   c                 @   | j         j        rd S | j        | j         k    r | j         | _        |                                  | j        r| j         | j        k     r| j        dz   d| j        dz   d}| j         dz   d| j         dz   d}| j        r3t          d| j        j	         d| j        j
         d| d| d	d	
           n;| j        | _         |s-t          d| j        j	         d| j        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            n# 1 swxY w Y   |s|s|s|                     d           d S d S d S d S )N<      ч    мr	  r   u   ) нельзя запланировать меньше Трудозатрат, чем запланировано в подзадачах ( < ub   ). Увеличьте Трудозатраты или уменьшите их у подзадач.Tr   u   ) указано Трудозатрат меньше, чем запланировано в подзадачах. Выставили uo   . Если нужно уменьшить Трудозатраты, уменьшите их у подзадач.rY   r   Fr~  workr]  )r   r   r  %_do_timetracker_sched_work_is_changedr   agregat_workrG   r   r   r   r   r  rW   rm   rQ  r   r-   r  r   rl   from_child_agregate_workrT  r/   r`  )	rP   from_sched_duration_changedr   r   r  r  r   r  r   s	            r5   _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TY^ A A#-A A2>A A A IMN N N N N '+&7DO- U! #Tdin #T #T #T #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   )A<G11G58G5c                 *   | j         j        rd S | j         | j        k     r| j        r=t	          d| j        j         d| j        j         d| j          d| j         d	d           n>| j        | _         t	          d| j        j         d| j        j         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 )Nr	  r   u   ) нельзя запланировать меньше Расходов, чем запланировано в подзадачах (r  uX   ). Увеличьте Расходы или уменьшите их у подзадач.Tr   u~   ) указано Расходов меньше, чем запланировано в подзадачах. Выставили ue   . Если нужно уменьшить Расходы, уменьшите их у подзадач.rY   r   Fr~  )r   r   agregat_cost
const_costr   r   r   r   rW   rm   rQ  r   r-   r  r   rl   from_child_agregate_costrT  r/   rP   r  r   s      r5   _do_sched_cost_is_changedz&CmfGanttTask._do_sched_cost_is_changed  sc   ?" 	F ?T... C sdin s s s s#s s373Ds s sz~@ @ @ @ @ #'"3 Bdin B B B B  PT  Pa 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<FFFc                 v    | j         r| j        r|                                  d S |                                  d S rT   )r    r   r  r   rU   s    r5    _do_actual_start_date_is_changedz-CmfGanttTask._do_actual_start_date_is_changed   sG    ! 	)d&: 	)$$&&&&&&&(((((rR   c                     | j         s$| j        r| j        r|                                  d S |                                  d S rT   )r    r!   r   r  r   rU   s    r5   !_do_actual_finish_date_is_changedz.CmfGanttTask._do_actual_finish_date_is_changed  sQ    % 	)$*A 	)dFZ 	)$$&&&&&&&(((((rR   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  rU   s    r5   #_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rR   c                 @    | j         r|                                  d S d S rT   )rC   r   rU   s    r5   _do_const_duration_is_changedz*CmfGanttTask._do_const_duration_is_changed  s1      	(%%'''''	( 	(rR   c                    | j         r|                                  d S g ddd| j        gg}| j        s t          j                            |          r|                     d d           d S d| _        | 	                                 d S )Nr^   ra   r[   r   TrW  rr  r1  )
r   r   r   r   r'   ro   r   rs  r   r<  )rP   _additional_task_filters     r5   _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:::::rR   c                 h    | j         j        dk    r| j         r|                     d           d S d S d S )NrB   unitsr]  )rO   r   r`  rU   s    r5   _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1rR   c                 n    | j         rd| _        | j        | _        d S | j        j        | _        d | _        d S Nr   )r4  r   r   r   defaultrU   s    r5   $_do_lock_sched_start_date_is_changedz1CmfGanttTask._do_lock_sched_start_date_is_changed2  sB    % 	-(1D%(,(=D%%%(,(A(ID%(,D%%%rR   c                 n    | j         rd| _        | j        | _        d S | j        j        | _        d | _        d S r  )r_  r   r   r   r  rU   s    r5   %_do_lock_sched_finish_date_is_changedz2CmfGanttTask._do_lock_sched_finish_date_is_changed:  sB    & 	.)2D&)-)?D&&&)-)C)KD&)-D&&&rR   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  r   r   Tr  rN  r3  )r   r3   r8   rl   r  r   r  r   r  r  r  r  r  r  r   r   r   r   r   r5  ri  rs  r/   rP   r   r   s      r5   add_child_task_to_parent_taskz*CmfGanttTask.add_child_task_to_parent_taskB  s    	F 
 
 
 	 	 	 (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.....rR   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 )N)r   r   r  r  z*remove_child_task_from_parent_task gt_id: r  z$, gt.actual_work to be substracted: T)rr  r3  )r   r  r  rj   r   r   r   r  r3   r8   rl   r  r   r  r   r  r  r  r  r  rs  r/   r  s      r5   "remove_child_task_from_parent_taskz/CmfGanttTask.remove_child_task_from_parent_taskg  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.....rR   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 rT   )r-   r  r   r   r   r  rQ  r  )rP   
old_parent
new_parents      r5   _do_parent_task_is_changedz'CmfGanttTask._do_parent_task_is_changedz  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)rP   argsrx  s      r5   _do_event_savezCmfGanttTask._do_event_save  s-     yB4BBB6BBBBBrR   c                     | |         j         S rT   )	log_level)rP   
field_namer  rx  s       r5   _get_field_log_levelz!CmfGanttTask._get_field_log_level  s    J))rR   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   r1  )7is_newr   r   rW   r   r8   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  r5  r   rc  r   r<  r   r   r  r   r  rC   r  r4  r  r  r  r_  r  rO   r  )rP   from_parent_changesr   r;  s       r5   _savezCmfGanttTask._save  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 6rR   uS   Вычисление плановых работ по ресурсам задачиgantt_task_id)descriptionshow_bg_progressbarrk  rl  rm  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: ro  r"   r[   history_typer[   planr  r\   r"   personr   r   rj  z4calc_resources_job start_res_assignment. task.code: z gantt_task_id: T)
assignment	work_leftrZ  r9  r  
create_tthz'calc_resources_job end. gantt_task_id: z task.code: )r  r  r'   r   r(   r   rl   r   CmfTimeTrackerHistoryrn   r-   r  deleteCmfTaskResAssignr   r   r   r   r   r   r"  r   _plan_resource_days)r  r2   r   tthassignmentsrZ  r9  r\  r  number_of_resourcesr  work_per_personwork_remainderr  r  s                  r5   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           
      X   d }d }	|j                             |                                | j        j        |o|                                          }
	 	 t          |
          }n5# t          $ r(}t          t          |          d           Y d }~nd }~ww xY w|j        j        }d}||                                k    r"t          |
                    |                    }t          |j        j        |z
            }|dk    rt          ||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          t2                              dk    r|}	nU||	fS )N)rZ  r   r9  Tr   r   r   r      ;   )hourminuter  )r9   r"   rZ  end_dater  
time_spentremaining_estimateF)r%   )r   	work_daysdater   r   nextStopIterationr   strr   get_work_time_shiftinterval_total_minutesr   r   get_shifted_work_timer   replacer'   r  r  r   r-   r  r/   r(   r   )rP   r  r  rZ  r9  r  max_work_per_dayr  
start_timeend_timedays_generatordayecur_date
time_shift
avail_timework_for_todaywork_for_today_remaindertth_start_datetth_end_dater  cur_max_work_for_todays                         r5   r  z CmfGanttTask._plan_resource_days(  sS   
#,66*//BSBSJN.J^CNCeS^ScScSeSe 7 g g1	.>**  . . .#a&&---------. 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'c1	f 8##s*   A$ $
B.BB	H,,H03H0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  rP   s   r5   check_exit_conditionsz;CmfGanttTask._calc_resources.<locals>.check_exit_conditionsg  ss    # t"a''t( t& t t~ $/ $:M t5rR   rB   z&_calc_resources start. gantt_task_id: r"   r[   r   --r\      r  rj  r  rD   r   T)r  )r  z4_calc_resources exit_conditions_met. gantt_task_id: r  rw  rJ   rH   r\  r  r  rF   i@8  )r  r   r   r   )r  r  )r  r\  z'_calc_resources finish. gantt_task_id: )*rO   r  r  rj   r   r"  r'   r  rp   rn   r-   r  r	  r   r   r   r   r   r   r
  r   r   r   r   r  r  r   r  r  r@  r  
date_startdate_endr   r  r/   r   r   sumvaluesr   r   )rP   r^  r  r3  _tth_filter	havy_taskr  rZ  r9  r\  r  initial_workinitial_durationr  	do_returnr  r  start_times	end_timesr#  r  r  r$  r%  r  s   `                       @r5   r`  zCmfGanttTask._calc_resourcese  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':'@@@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':'@@@6646PPP G++@U0U0U22t2LLL
**4?#88822t2LLL!%@@@&&+;t?R?X+X+X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..O2	5O2	c                     |                      |                                            | j        p| j        }|r|                     |           d S d S rT   )r   rl   r   r   r  rP   r"   s     r5   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 	7rR   c                     |                      |                                            |                                  |                     d|           |                                  |                     d           d S )Nr  )r^  r  Tr3  )r   rl   r,   r`  rU  r/   )rP   r  s     r5   task_resources_changed_hookz(CmfGanttTask.task_resources_changed_hook  sy    1133444!!!7LLL**,,,		D	!!!!!rR   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 )NTr3  r  )r   rl   r,   r  r  r/   r  r  )rP   r  r  from_tth_restores       r5   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	!!!!!rR   c                     |                      |                                            |                                  | xj        |z  c_        |                                  |                     d           d S NTr3  )r   rl   r,   r  r  r/   r  s     r5   timetracker_add_cost_hookz&CmfGanttTask.timetracker_add_cost_hook3  st    1133444!!!:-..000		D	!!!!!rR   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 )Nr   task.parentF
CmfProjectTr3  )
r   rl   r   r"   r   
class_namer   r   check_gantt_projectr/   )rP   	need_saves     r5   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%%%%%	& 	&rR   c                 .    |                                   d S rT   )r  rU   s    r5   r  z2CmfGanttTask._do_timetracker_sched_work_is_changedJ  s    ""$$$$$rR   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_PROGRESSTr3  r   r   r   )r%  r    r   rl   r,   set_nowr  !_pass_actual_dates_to_sched_datesrU  r/   r!   r  r  r  r  )rP   
old_status
new_statuss      r5   task_status_is_changed_hookz(CmfGanttTask.task_status_is_changed_hookM  s|     		*0MAA$J`AT5577888##%%%"**,,,1133322444..000III%%%F 	*0H<< =#-#9X#E#ET5577888##%%%#++---#&D 22444//11122444..000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#ErR   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   r3  u(   Плановые даты задачи "r   u   ) не изменились                            при попытке выставления дат от спринтов из-за ошибки: "r{  N)r   rl   r   r   r,   r   plan_start_dater   plan_end_dater   r   re  rU  r  rP  r/   CmfAbortErrorr   r   r  )rP   r(  s     r5   task_plan_dates_is_changed_hookz,CmfGanttTask.task_plan_dates_is_changed_hookx  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 rJ  )r   rl   rP  r/   rU   s    r5   task_logic_type_is_changed_hookz,CmfGanttTask.task_logic_type_is_changed_hook  sN    1133444  """		D	!!!!!rR   c                     |                      |                                            | j        j        | _        | j        j        r|                                  d S d S rT   )r   rl   r   r   r   r/   rU   s    r5    task_parent_task_is_changed_hookz-CmfGanttTask.task_parent_task_is_changed_hook  sX    113344490& 	IIKKKKK	 	rR   c                     |                      |                                            | j        j        | _        |                                  d S rT   )r   rl   r   r   r/   rU   s    r5   "task_gantt_project_is_changed_hookz/CmfGanttTask.task_gantt_project_is_changed_hook  s@    1133444!Y4		rR   c                     |                      |                                            | j        r&d | _        d| _        |                     d           d S d S )Nr1  Tr3  )r   rl   r   r   r/   rU   s    r5   $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%%%%%	& 	&rR   c                     |                      |                                            |                     d d           |                                  |                                  |                     d           d S )NTr  r3  )r   rl   rs  rS  rT  r/   rU   s    r5   *additional_children_relations_changed_hookz7CmfGanttTask.additional_children_relations_changed_hook  sz    1133444,,PT,UUU'')))		D	!!!!!rR   c                 L    | j         j        rd| _         | xj         |z  c_         d S r   )r  r   )rP   r  s     r5   r  z CmfGanttTask.from_child_add_work  2    # 	! DJ&rR   c                 L    | j         j        rd| _         | xj         |z  c_         d S r   )r  r   r  s     r5   r  z CmfGanttTask.from_child_add_cost  rk  rR   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   rY   Fr~  )r  r   rG   r   rQ  r   r   r   rW   rm   r-   r  r   rl   r  rT  r/   )rP   r  r  r   r   s        r5   r  z%CmfGanttTask.from_child_agregate_work  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   Превысили План на Расходы (rn  ro  u[   . Увеличьте в ней план или введите меньше РасходовTr   rY   r3  )r  r   r  r   r   r   rW   rm   rQ  r   r-   r  r   rl   r  r/   r  s      r5   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/  )rP   r&  s     r5   !from_child_update_actual_completez.CmfGanttTask.from_child_update_actual_complete  s     	++,ABBBBBrR   c                 `   |                                  sdS t                                          5  |                                  }|                    |                                            |                    |            |                    d           ddd           n# 1 swxY w Y   dS )uP  
        Оповещение родителя.
        Передаем себя, т.к. мы еще можем быть не сохранены и родитель не сможет получить наши данные
        Другой вариант: опочещать через отдельный таск в celery
        NFr  )rW   r-   r  r   rl   rr  r/   )rP   r   s     r5   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 rc   rc   )rg   k_s      r5   	<setcomp>z0CmfGanttTask.check_user_input.<locals>.<setcomp> 	  s    JJJFQaJJJrR   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   r8   check_project_role_accessr  r   r   r  r   r   r  rP   changed_fieldss     r5   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,irR   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_slackrU   s    r5   r,   zCmfGanttTask.fix_null_variables	  s,   # 	! D$ 	" !D?" 	 DO# 	! D& 	$"#D' 	%#$D $ 	" !D?" 	 DO"* 	(&'D#' 	%#$D ' 	%#$D #+ 	)'(D$# 	! D	! 	!rR   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: rY   T)r   r   r3  )z	task.epicztask.subprojectrj  )r   r  level)r   r   r  )r  r  rj   r   rm   r   r   r   r3   r   rl   rP  r/   boolr   r   r   r   r   r   _calc_gantt_projectr   rx   _calc_outline_numberrW   r  r  )
rP   r  r   r   from_importr  plan_fields_are_usedrV  rW  r   s
             r5   rP  z CmfGanttTask.check_gantt_project4	  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rR   c                 x   t                               d| j        j        j         d| j        j        j         d|            |dk    r,t          d| j        j         d| j        j         dd	           |s| j        j        }d
d| j        gddg dgg}d t          j	        
                    |g d          D             }d }t          j                            ddt          |                                          gg dgg d          }|D ]N}||j        j        j                 \  }}	d }
|j        j        }|dk    r0|j        j        }
|	r!t          j                            ||
|	          }
n|dk    r?|j        j        }
| j        j        pd|	z
  }t          j                            |||          }n}|dk    r0|j        j        }
|	r!t          j                            ||
|	          }
nG|dk    r?|j        j        }
| j        j        pd|	z
  }t          j                            |||          }n#|
r|s)t          j                            |||
          r|} nP|s[| j        rT| j        j        }|                    |                                           |j        s|                    ||dz             }|S )Nz0_get_task_blocking_back_movement start task_id: r  z
), depth: r   u[   DEV: Защита от рекурсии: _get_task_blocking_back_movement: if depth > 100 "r   r|  Tr   ra   r[   r_   rk   system.finish:startsystem.finish:finishsystem.start:startsystem.start:finishc                 N    i | ]"}|j         j        |j        j        |j        pd f#S r   )rd   rj   relation_typer   r2  rf   s     r5   
<dictcomp>zACmfGanttTask._get_task_blocking_back_movement.<locals>.<dictcomp>	  sA     "
 "
 "
 LOc/4c6G6L1M"
 "
 "
rR   )rd   r2  r_   r\   r?  r"   r[   N)z	task.nameztask.idr   r   project.calendar.timezoner  r  r   r  r  rj  )target_datedepth)r  r  r   r   r   r   r   r   r'   ro   rp   r   rn   keysrj   r   r   r   r   r   r   r   r   r3   r   rl   r    _get_task_blocking_back_movement)rP   r  r  
_filter_inbefore_tasks_with_lagsblocking_gantt_taskbefore_gantt_tasksbefore_gantt_taskrel_type_coder2  before_dater   r\  r   s                 r5   r  z-CmfGanttTask._get_task_blocking_back_movement	  s   	  C49>CW  C  C[_[d[i[o  C  C  |A  C  C  	D  	D  	D3;;  Ytxt}  uC  Y  Y  HL  HQ  HV  Y  Y  Y  ae  f  f  f  f 	6/5K di(!4  *F  *F  *F  G

"
 "
/55Z  QD  QD  QD5  E  E"
 "
 "
 ##055d+A+F+F+H+H&I&IJLbLbLbcqqq 6 
 
 "4 	 	+ABSBXB[Ba+b(M=K(09H 555/AG  p"("4"I"I(T_an"o"oK"888/AG /5:mK$0EEhP[]eff"666/@F  p"("4"I"I(T_an"o"oK"777/@F /5:mK$0EEhP[]eff k  !66xkZZ &7# # 	Ct'7 	C $ 0 >))*;*O*O*Q*QRRR$. C&7&X&Xepx}  AB  yB&X  'C  'C#""rR   c                    | j         j        s| j        j        rYt                              d| j        j        j         d| j        j        j         d| d| j         j	         d| j         j
         
           | j         j	        o%| j         j
        o| j         j	        | j         j
        k     }| j        j	        o%| j        j
        o| j        j	        | j        j
        k     }|s|r7|r5|                                 }|rt          d|j        j         dd	           d
d| j        gddg dg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   Перемещение заблокировано задачей "uz   " с исходящей связью ОН/ОО/НН/НО. Удалите связь и попробуйте еще раз.Tr   rd   r[   r_   rk   r  r   r?  rw  )r   r   r   r  r  r   r   r   r   rQ  r   r  r   r'   ro   r   r  sort_task_by_order_relationsrj   )rP   	from_savefinish_date_is_chagnedstart_date_is_chagnedblocking_task_filter_outs         r5   rU  z*CmfGanttTask._check_start_finish_relations	  s@   !, 	0E0P 	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 &*%;%?  &[DDZD^  &[cgcyc}  AE  AW  A[  d["$($9$=  %V$BWB[  %V`d`u`y  }A  }R  }V  aV!& o*? oY o $ E E G G  o bcpcucz b b bimo o o o T49-%t  .J  .J  .J  KK ',,K,@@ %f&>&[enptpyp|d}~~~~~~%	 	" rR   )r  r  from_sort_orderc                >   |r!|                                    | j        |i | |                     |           | j        j        r| j                            d           |                                  |                                  |                                  | 	                                 | 
                                 |                                   t                      j        |i |}| j        j        r=t          j                            | j        | j                                                   | j        j        r=t          j                            | j        | j                                                   |s|                     d           |S )N)r  Tr3  )r"   r   )r  )r  r  r  r   r   r/   rW  rP  r,   _alert_task_agile_plan_datesr  rS  r   r   r'   
CmfCommentadd_comment_audit	html_diffr   rU  )rP   r  r  r  r  rx  r   r   s          r5   r/   zCmfGanttTask.save	  s    	1!!###D0000

':
;;; 9 	+INNTN***..000  """!!!))+++!!###egglD+F++ + 	j//tytG\GfGfGhGh/iii!, 	k//tytG]GgGgGiGi/jjj 	?...>>>
rR   c                 b    |                                    t                      j        |i | d S rT   )r   r   _save_import)rP   r  rx  r   s      r5   r  zCmfGanttTask._save_import
  s7    !!###d-f-----rR   )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_numrz   T)r3   include_deletedr3  uY   Нельзя удалять Оперативную гант задачу у задачи!r   r  )r   r   outline_remover   r  r  rj   r'   r#  rn   r3   r/   r   r   r  r   r	  )rP   r  r  r  rx  r   r   s         r5   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QrR   c                     |                      g d            t                      j        |i |}| j        r1| j        j        | k    r!|                     | j        p| j                   |S )N)r  r   r   )r   r   restorer   r3   r  r   r   )rP   r  rx  r   r   s       r5   r  zCmfGanttTask.restore
  sv    OOOPPPeggot-f--9 	W0D88..t/?/U4CUVVV
rR   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 endrc   )r   before_save_hookr  r  r  r'   CmfAutomationCrudTrigger	crud_hookrP   rx  r   s     r5   r  zCmfGanttTask.before_save_hook(
  sv      **6***; 	F	1222'11$-PPP	/00000rR   c                      t                      j        di | | j        rd S t                              d           t
          j                            | dd           t                              d           d S )Nr  r  
after_saver  rc   )r   before_save_data_hookr  r  r  r'   r  r  r  s     r5   r  z"CmfGanttTask.before_save_data_hook2
  sv    %%/////; 	F	1222'11$,OOO	/00000rR   r  c           	      :   t           j        r| j        sd S t           j        t           j        j        j        dg|| j        j        |                     d          t           j        | j        j        d}t          d|d          ||d         |d         g           d S )Nproject_notifyTry  )initiatorSessionTabIdinitiatorCurrentPersonactioninitiatorActioninitiatorObjIdinitiatorObjChangedFieldsu   initiatorСomponentId	projectIdzproject_notify-r  )roomevent_persons)	r  session_tab_idrK   current_personrj   r   r  component_idcmf_emit_event)rP   initiator_actionevents      r5   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rR   c                    | j         s| j        sd S | j        j        r2| j        r+| j        s$| j        | _        |                     d           d S | j        j        r2| j        r+| j        s$| j        | _        |                     d           d S | j        j        r| j        s| j        j        r7| j        r2| j        | _        | j        | _        |                     d           d S d S d S )NTr  )	r   r>   r    r   r!   r   r5  r   rc  rU   s    r5   rW  z.CmfGanttTask._pass_actual_dates_to_sched_datesU
  s,    	t'J 	F!, 	1G 	PTPg 	$($:D!00T0BBBF"- 	$2I 	RVRh 	%)%<D"11d1CCCF #.	373J	'2	7;7M	 %)$:D!%)%<D"11d1CCCF	 	 	 	rR   c                    t           j                            |           }|sd S |                    |                                           |j        rt          d           d S d}|j        r|j        |_        |j	        r|j	        |_
        |j        j        r#|j
        j        s|                                 d}n"|j
        j        r|                                 d}|r|                    d           d S d S )Nro  u   Нельзя пробрасывать фактические даты в плановые у родительских задачFTr3  )r'   r   r(   r   rl   r   r   r    r   r!   r   r   r5  rc  r/   )r  r2   
needs_saves      r5   r   z3CmfGanttTask.force_pass_actual_dates_to_sched_datesl
  s+   (,,,>>
 	Fz==??@@@% 	  Y  Z  Z  ZF
' 	G*4*FJ'( 	I+5+HJ(&1 	*:V:a 	77999ZZ)4 	88:::Z 	,OOdO+++++	, 	,rR   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   ) выходит за диапазон плановых дат спискrj  u   аu   oв: r  z),,)r   r   r   r   r\  r]  r   listsr@  r   r   r"  r   rstrip)rP   alert_start_datealert_end_datealert_lists	task_listrh  lsts          r5   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&&&&&	' 	'rR   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 )NrY   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   rm   r  r   r   rQ  r   r   
astimezoner   r   r   r   r   divmodstrftimer   r   r   )rP   r#   r   r  r4   new_value_strold_value_strold_hour
old_minutenew_hour
new_minutedate_olddate_newr  r  time_suffixs                   r5   rT  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&	^ &	^rR   c                    g }| j         j        r|                    d           | j        j        r|                    d           | j        j        r|                    d           |rVt
          j                            g ddd| j        gg          r,t          t
          j        j
        | j        |d	           d S d S d S )
Nr   r   r   )r"   rL  Nr?  r[   r   )r?  r  rw  )r   r   r@  r   r   r'   r   r   r?  r  calc_variance_jobr  s     r5   rS  zCmfGanttTask.calc_variance
  s     + 	6!!"4555!, 	7!!"5666) 	4!!"2333 	f166?U?U?UXacgimiuWv>w6xx 	!#5#'<*8: :     	 	 	 	rR   r  u<   Расчет отклонения задачи от baseline)rk  rl  rm  r  c                 ^   d }t           j                            | ddg          }|sd S |j        }|                    |                                           t           j                            dd|j        gdgdg	          D ]&}t           j	                            d
d| gdd|gg|                                          }|sAd|v r. ||j
        |j
        |                                          |_        d|v r. ||j        |j        |                                          |_        d|v r|j        pd|j        pdz
  |_        |                    d           |j        rH|j        |_        |j        |_        |j        |_        |                    d           t'                       (d S )Nc                     | }|}d}|rE|rC||k    r=||k    r||}}d}t           j                            ||j        |j                  }||z  S dS )Nrj  r   r   r   r   )r'   r   r   r   )	date_taskdate_baseliner   r   r   signresults          r5   _calc_dates_variancez<CmfGanttTask.calc_variance_job.<locals>._calc_dates_variance
  s}    G!ED 	%5 	%W%5%5U??%*GUGD+@@%#M+ A  
 }$1rR   rK   r3   rp  r"   r[   z-active_baselineactive_baseline)r]   order_byr#   r?  r\   r   r   r   r   Tr3  )r'   r#  r(   r3   r   rl   CmfGanttBaselinern   rK   r   r   r   r)   r   r*   r   r+   r/   r   
cmf_commit)r?  r  r  r   r2   r1   baseline_gantt_tasks          r5   r  zCmfGanttTask.calc_variance_job
  s#   
	 	 	$ ~!!WlO5T!UU 	F'
z==??@@@/44XtT_<]?Q>R=N<O 5 Q Q 	 	H #)"5"9"99dT[B\CKTS[B\B^AKA_A_AaAa #: #c #c ' !^335I5IJ]JnJTJeJTJbJbJdJd6f 6f#2 #n446J6JK^KpKUKgKUKcKcKeKe7g 7g#3  >119C9R9WVW\o\~  ]D  CD  9E#5$$t$444' ,?,N
)-@-P
*/B/T
,$///9	 	rR   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 )NrY   r   )remove_from)r   r   r   r   rm   outline_numberoutline_parent_strr  r   r  outline_insert_downr  rB  s     r5   r  z!CmfGanttTask._calc_outline_number3  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$$&&&&&	' 	'rR   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  Nrj   rL  )r#   r  r]   rj  r   06r  )_outline_lock_lvlr   rj   r   r  r3   r  r-   r  r'   r   r(   r  r  r   r   r   r  _outline_recalc_childrens)rP   	max_indexs     r5   r	  z CmfGanttTask.outline_insert_downU  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  r|   zop_gantt_task.outline_index_numr   rp  u   outline_insert_after можно вызывать только для задач на том же уровне. Сначала измените parent_taskTr   rj  Fr  r   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
        )rz  r{  rj   from_outline_index_numto_outline_index_numic                     g | ]
}|d          S r?  rc   rg   rs     r5   ri   z5CmfGanttTask.outline_insert_after.<locals>.<listcomp>      ///aQy\///rR   c                     g | ]
}|d          S ro  rc   r  s     r5   ri   z5CmfGanttTask.outline_insert_after.<locals>.<listcomp>      000q1T7000rR   r  )r   r  r   rj   r   r'   r#  r(   r   r  r   r3   r  r  	CmfPersondp_ddSessionexecuter   r   r@  r  r   r  )rP   prev_task_id	prev_taskold_outline_index_numprev_outline_index_num	insert_upr  r  r  sqlr   	child_idschild_gantt_idss                r5   r   z!CmfGanttTask.outline_insert_aftert  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rR   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
        )rz  r{  r#  rj   c                     g | ]
}|d          S r  rc   r  s     r5   ri   z/CmfGanttTask.outline_remove.<locals>.<listcomp>  r  rR   c                     g | ]
}|d          S ro  rc   r  s     r5   ri   z/CmfGanttTask.outline_remove.<locals>.<listcomp>  r  rR   r  r  rp  )r  rj   r   r  r   r  r  r   r'   r  r  r  r  r   r  r   r  r   r3   r   )rP   r  remove_from_idr#  r&  r   r'  r(  s           r5   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rR   c                 F    t                               d| d|            d S )NOUTLINE_NUMBER_rw  )r-   cache_obj_lock_get)r0   r{  rz  s      r5   r  zCmfGanttTask._outline_lock_lvl  s0     	""#X5E#X#X#X#XYYYYYrR   uY   Вычисление структурных номеров у дочерних задач)r  rm  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_listr{  r   r?  rj   )r  r  r"  r'   r   r  r  r  r  r  r   tupler@  )
parent_id_list	parent_idr&  r   recursive_parent_id_listtfinish_gantt_invalidatefinish_invalidater{  recalc_subtrees
         r5   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 9rR   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#  rO  r   )idsgantt_task_idsr{  r8  r9  r:  s     `@@@r5   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1rR   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 )Nr4  rj   )rm   r  rY   T)r#   r]   include_systemc                     g | ]	}|j         
S rc   ro  r  s     r5   ri   z6CmfGanttTask._outline_force_recalc.<locals>.<listcomp>#  s    $7$7$7aQT$7$7$7rR   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
                )rz  r{  r   r?  z&_outline_force_recalc cache invalidatez-_outline_force_recalc finish cache invalidate)r'   r#  rp   r  r  r"  r  r  popr  r  data_driverr  r   r  r;  r<  r=  r>  rO  rn   )r{  gantt_project_id_listr   process_parent_id_setrz  r&  clean_cache_idsr7  s           r5   _outline_force_recalcz"CmfGanttTask._outline_force_recalc  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rR   c                 J    t          t          j        j        d| i           d S )NrK   rw  )r  r'   r   calc_critical_path_job)rK   s    r5   r   zCmfGanttTask.calc_critical_pathl  s(    f1HR^`jQkllllllrR   rK   u.   Расчет критического пути)rk  rl  rm  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 )Nrj   r[   r\   )r'   r   r(   )r  r2   r#   gantt_tasks_by_ids     r5   _get_gantt_taskz<CmfGanttTask.calc_critical_path_job.<locals>._get_gantt_tasku  sH     $555#044T4<W`f4gg
3=!-0$]33rR   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 )
NrK   r[   )r{   r[   rY   r  r   r\   uW   Не найдена гант-задача у гант-проекта в проекте Tr   )rK   r'   r   r(   r   r   r   )r2   r   _fieldsgantt_project_gtproject_end_datess       r5   _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%:;;rR   c                     | j         vrM|                     ddg           | j        j        p!t          j                            ddg          | j         <   | j                  S )Nzproject.calendarr  rH  r   rI  )rK   r   r   r   r'   r   r(   )r2   calendars_by_project_ids    r5   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ArR   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 r7t#          dt$          j        j         d	t$          j        j         d
d           n                    |j         j                   |}|j         j        v rg }|r|                    |           |j         j                 D ]\  }}  |          |dz              |v r]|         j        }	|r9t.          j                             |          |	t5          |                     }	|                    |	           |rt7          |          }|j        j        s||_        t.          j                             |          |j        j        t5          |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t7          ||j                  n|j        }|r|j        rtA          ||j                  n|j        }|r|j        rt7          ||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t7           |          |          |_        n |          |_        t.          j                             |          |j        j        t5          |j                             |_        t.          j                             |          |j
        j        |j        j                  |_        |j        j        dk    |_        |                    d            |j        j        |j        j        |j        j        |j        j                  |j         j        <   d S )NFTr3  rj  zcalc_critical_path: level: z, )r  uQ   calc_critical_path: Обнаружен цикл в связях в задаче "r   r|  r   )r   r   r\  r  r   zchild_tasks.op_gantt_taskc                 &    g | ]}|j         j        S rc   )re   r   )rg   r7  s     r5   ri   zRCmfGanttTask.calc_critical_path_job.<locals>._calc_is_critical.<locals>.<listcomp>  s    *i*i*i1+=+C*i*i*irR   )late_start_datefrom_parent_taskr  rY  late_finish_dater  is_critical_path)"rj   r   r(   r   re   rY  r\  r  r]  r   r   r   r   r/   r  r  r   r   rP   r   r   r  r@  r'   r   r   r   r   r   r   r   rV  r   r   )r  rY  rZ  r  r2   #following_tasks_min_late_start_datefollowing_late_start_datesfollowing_gantt_task_idr2  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   rO  rT  done_gantt_tasksgiven_late_start_date_by_gt_idtask_out_linksvisited_gantt_taskss                    r5   rj  z>CmfGanttTask.calc_critical_path_job.<locals>._calc_is_critical  s   (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  Snrnwn|  S  S  BF  BK  BP  S  S  S  [_  `  `  `  `  `#''
(;<<<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1rR    main_gantt_project.op_gantt_taskrp  u   Проект с id "u   " не найден.Tr   )rq  rr  ri  r[  )	r   r   r   r   r|   rz   r   rY  r\  r   r[   )r{   rL  rY   r  c                 (    i | ]}|j         j        |S rc   )rj   r   )rg   r2   s     r5   r  z7CmfGanttTask.calc_critical_path_job.<locals>.<dictcomp>I  s1      H  H  HZ]0*  H  H  HrR   r\   )NFN)r'   rN  r(   r   main_gantt_projectr3   r   rl   rs  ro   get_start_finish_graphsr  r   dictr   r   rK   r   rn   r  )rK   r   gantt_project_gantt_taskrw  r   r  ri  rj  r   rO  rT  rV  rk  r#   rN  rl  rS  rm  rn  s         @@@@@@@@@@@@@r5   rK  z#CmfGanttTask.calc_critical_path_jobp  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,,,,	- 	-rR   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   r[   ro  )r#   r]   r   rM  rY   )r~   r[   Nry  )r  rL  N)r  rL  r   )r   rL  N)r   rL  r   )r  rL  N)r  rL  r   )r   rL  N)r   rL  r   )r  r   r  r   T  cmf_created_at)slicer]   r#   r  r3  )r'   rN  rn   rq  r3   r  r  r  r  r   r   r   r   r/   r  )	project_codeproject_filterr   r   r]   r#   r  r  r2   s	            r5   recalc_gantt_projectsz"CmfGanttTask.recalc_gantt_projectsN  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	rR   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 )Nrv  r   T)r]   r#   rx  include_archived)r  r'   r#  rp   rz  r{  r   re   r  r   cmf_deleted)
parent_idslimitsteptasksr   rQ  r   trees        r5   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%( rR   )r   r[   F)zparent_task.op_gantt_task_idzgantt_project.op_gantt_task_idre   zparent_task.cmf_deleted)r  r[   factr5  c                 ^    h | ]*}|j         	|j                             d           #|j         +S )r#  )r5  
startswith)rg   r  s     r5   rx  z.CmfGanttTask.get_gantt_tree.<locals>.<setcomp>  sQ     'a 'a 'a*--'a<?M<T<TU^<_<_'as} 'a 'a 'arR   T)r]   r~  r#   rj   rk   re   )r   r  rn   r'   r  rp   r  )
leaf_filterr  parent_ids_set
tth_filter
tth_fieldstask_ids_from_tth_factparent_ids_set_from_tthrQ  r   r  s
          @@@r5   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  	+ rR   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_datar  s       r5   r  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%%rR   ry  )op_gantt_task.actual_workrL  N)r  rL  r   )op_gantt_task.sched_workrL  N)r  rL  r   )op_gantt_task.actual_costrL  N)r  rL  r   )op_gantt_task.sched_costrL  N)r  rL  r   )%parent_task.op_gantt_task.actual_workrL  N)r  rL  r   )$parent_task.op_gantt_task.sched_workrL  N)r  rL  r   )%parent_task.op_gantt_task.actual_costrL  N)r  rL  r   )$parent_task.op_gantt_task.sched_costrL  N)r  rL  r   u(   Получаем дерево задач)r  c                      dddddddS )Nr   )r  r   r  r   r  r  rc   rc   rR   r5   <lambda>z0CmfGanttTask.recalc_gantt_tree.<locals>.<lambda>  s(    [\lm  @A  ST  )U  )U rR   c                     h | ]	}|D ]}|
S rc   rc   )rg   r  childs      r5   rx  z1CmfGanttTask.recalc_gantt_tree.<locals>.<setcomp>$  s%    QQQQQuuQQQQrR   r  Fc                     i | ]
\  }}||pd S r  rc   )rg   tidss      r5   r  z2CmfGanttTask.recalc_gantt_tree.<locals>.<dictcomp>8  s"    888VS!3a888rR   rv  r   )r4  r  r  r   r   r  r  rj   rk   T)r]   r#   r  r  r  0r  r  r  r   r   rj  
   u   Обработано u    из u    ветокr  r  )r  r  r   r   r  r  u:   Обновленные данные внесены в БДu/   Нет данных для обновленияN)0printr'   r   r  r   dp_modelr  r#  r  rE  r  r  r  r9  rn   queryrj   r
   r8  r  joinr?  r5  r]   r   in_r  r  group_byallranger"  rp   r  r  r   r(   r  r   r   r   	__table__r  wherer	   r  r=  flushdb)r  	GanttTaskTimeTrackerHistorysessionparent_nodeschild_nodes
root_nodes	all_nodestth_rowstth_sum
batch_sizer  	batch_idsr#   r  r2   progress_countrootr  r  r  s                     @@@r5   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DrR   calendar_idc           
      6   t           j                            g dg dddt          j                                        ggddd| gg dd	d| gggg
          }d}|D ]}|                    |                                           |j        rr|j	        s|j
        rd|j	        rd |_
        |                    d           |                    d           |                                 |                    d           |dz  }|dz  dk    rt                       d S )Nr  rz  r   >ry  ztask.responsible.calendar_idr[   )r}   r[   Nztask.project.calendar_idr   r   TrO  r  r]  r3  rj     )r'   r   rn   r   r   r   r   rl   r   r   r   r  r`  rU  r/   r  )r  r  processed_tasksr2   s       r5   recalc_gantt_tasks_by_calendarz+CmfGanttTask.recalc_gantt_tasks_by_calendarf  se    )..&&&1114GbkooN_N_3`a3T;G5558RTXZe7fg / 	
 	
 % 	 	J"":#A#A#C#CDDD( 0j.I 0ZMi 0. 837J0--t-<<<***AAA88:::$///q O#q((	 	rR   rT   )NFF)FFF)FF)F)NFNF)FFFFF)FFFF)NF)NN)FFNFr   r   )r  )~__name__
__module____qualname__	api_allowr   api_methodsclassmethodr6   r?   r;   r<   rW   rx   rl   propertyr   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r/  r<  rF  r   rR  r5  rc  re  ri  staticmethodcmf_deferred_jobru  rs  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`  rC  rE  rH  rK  rR  r  rZ  r_  ra  rc  re  rg  ri  r  r  r  r  rr  r  r  r,   rP  r  rU  r/   r  r	  r  r  r  r  rW  r   r  rT  rS  r  r  r	  r   r  r  r  rI  r   rK  r{  r  r  r  __classcell__)r   s   @r5   r   r      s2       I*  .F  .F  .F  FK  [.    [@6 6 6 - - -
4 4 4 46dW\ ! ! ! !B4 4 4 4 48 I I XI   X   X   X6   X*( ( ( (T+ + + +\)9 )9 )9V]9 ]9 ]9~, , ,b b b bB% % %       4! ! ! !,'F 'F 'F 'FV  (@ @ @*B7 B7 B7 B7H]" ]" ]"~" " ":R R R6? 6? 6?p> > > >2> > > >$7 7 7n n n i[1MMM" " NM \" [# [# [# [#zJ J J J8S S S.L L L2E" E" E"N ejY^:?B? B? B? B?H# # #!\ !\ !\ !\F9 9 90   K K K K* * * _dV[;7 ;7 ;7 ;7zI I I.) ) )) ) )  ( ( (; ; ;8 8 8- - -. . .#/ #/ #/ #/J/ / / /&? ? ?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;$ ;$ ;$ ;$zdE dE dE dEL7 7 7" " "" " " "6" " "& & & % % %) ) )VK K K0" " "
    
& & &" " "' ' '
' ' '
I I I47 7 7(C C C C  "& & &4! ! !:LG LG LG LG\=# =# =# =#~   , &*uV[ ( ( ( ( ( ( (T. . . . . .3U R R R R R R R2    1 1 1 1 11 1 1 1 1C C C C2  . , , \,:' ' 'B2^ 2^ 2^h    iAQ5R .ln n n7 7n n \7B '  '  '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p m_qQQQ  RQ \    rR   r   )r   r   dateutil.tzr   decimalr   r   r   collectionsr   r   
sqlalchemyr	   r
   r   r  
cmf.fieldscmf.include#modules.gantt.fields.cmf_gantt_taskr   rc   rR   r5   <module>r     s              7 7 7 7 7 7 7 7 7 7 / / / / / / / / , , , , , , , , , ,          < < < < < <q9 q9 q9 q9 q9< q9 q9 q9 q9 q9rR   