
    {Ci)                        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 d dl d dlmZ  G d d	e      Zy)
    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_ddaZ`ddbZaddcZbdd	d	dd fde
Zc fdfZdd	d	dg fdh
Ze fdiZf fdjZg fdkZhddlZidm Zje)dn        Zkdo Zldp Zmdq Zne) e*dd&drgd'dst      du               Zodv Zpdw ZqddxZrdy Zseddz       Zte) e*d{d'|      d}               Zue) e*d~d'|      dd              Zve)d        Zwe) e*ddgd'dd      d               Zxe) e*dd'|      dd              Zye)dd       Zze)d        Z{ xZ|S )r   T)outline_insert_aftercalc_critical_path&force_pass_actual_dates_to_sched_datesc                 p   t         j                         }g d}t         j                  j                  d ||      }|r$|D ]
  }||   ||<    d|_        d|_        d|_        ||_        |j                          t        j                         5  |j                  ddd       d d d        |S # 1 sw Y   |S xY w)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   s    ((*
T ++//t$v/V 9$1%$8
5!9 )*J%)*J&+,J($
%%'##% 	FOOuOE	F	Fs   B++B5Nc                 p   t         j                         }|r| j                  ||      S |j                  j	                          |j                  |_        ||_        |j                  |_        |j                  |_        |j                          |j                          |j                  |_
        |j                  r?|j                  j                  j	                          |j                  j                  |_        t        j                         5  |j!                  dd       d d d        |S # 1 sw Y   |S xY w)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*   s    ((*
66tXFF 	!#'#5#5
 
  $~~
 $
 	  "!%!1!1
@@EEG8B8J8J8l8lJ5##% 	6OOuO5	6	6s   D++D5c                 8   | j                   r| j                   j                  rqt        j                  | j                   j                        j                  }|dk(  rd| _        |dk(  rd| _        |dk(  rd| _        |dk(  rd| _        |d	k(  rd
| _        y y d| _        y )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    99--001E1EF^^Lx''1$//'9$//'9$|+'5$88'B$ 9 $6D     c                     | j                   r3| j                   j                  r| j                   j                  | _        y y y N)r   r   rP   s    r5   r<   zCmfGanttTask._calc_project[   s-    99**99,,DL +9rR   c                     | j                   r| j                   j                  S | j                  r| j                  j                  S y rT   )r   r3   r   rU   s    r5   _get_parent_gantt_taskz#CmfGanttTask._get_parent_gantt_task`   s=    ##111%%333 rR   Fc                    || j                         }| j                  j                  dk(  rEt        j                  j                  g ddd| j                  gdd| j                  gg|gz   |      }nAt        j                  j                  dd| j                  gdd| j                  gg|gz   |      }|rt        j                  j                  g dd	d| j                  ggd
g      }|r]|D cg c]  }|j                  j                   }}t        j                  j                  dd|gg|gz   |      }|j                  |       |S c c}w )Ntask.gantt_projectr   ==Nr   r[   r"   filterr#   r   relation_type.coder[   system.additional_parentin_linkzout_link.op_gantt_task_ididIN)save_preload_fieldsr   logic_prefixr'   r   listr"   CmfRelationOptionslistout_linkop_gantt_task_idextend)	rP   
add_filterr#   include_additionalchild_gantt_tasks additional_child_tasks_relationsreladditional_gantt_task_idsadditional_gantt_taskss	            r5   _get_children_gantt_tasksz&CmfGanttTask._get_children_gantt_tasksf   s   >--/F99!!%99 & 3 3 8 8/$dDII6tT[[1  L	!
  !9 ! !' 3 3 8 8"D$))4tT[[1  L!  !9 ! /5/G/G/M/M  WO  R[  ]a  cg  cl  cl  Qm  VnToSp 0N 0r,/Vv,wsS\\-J-J,w),w)/)<)<)A)A4QUWpJqIr  wA  vB  JB  KQ)A  *R&!(()?@  	 -xs   -Ec                 .    g d}t         |          |z   S )N)r   r"   r   r   zgantt_project.op_gantt_taskr   zparent_task.gantt_projectparent_task.op_gantt_taskz(parent_task.op_gantt_task.outline_numbertask.logic_prefixztask.parent_task.logic_prefixtask.has_child_tasksztask.plan_start_dateztask.plan_end_dateztask.responsibleztask.responsible.calendarz"task.responsible.calendar.timezoneztask.executorstask.parent_taskztask.is_milestone task.gantt_project.op_gantt_task)superrd   )rP   r#   	__class__s     r5   rd   z CmfGanttTask.save_preload_fields   s    
. w*,V33rR   c                     | j                   j                  ry | j                   | j                  z  dz  }t        |      j	                  t        d      t
              S )Nd   z1.11rounding)r   is_null_perform_completeDecimalquantizer   rP   ress     r5   _perform_costzCmfGanttTask._perform_cost   sI    ??""oo 6 66<s|$$WV_x$HHrR   c                     | j                   j                  ry | j                   | j                  z  dz  }t        |      j	                  t        d      t
              }t        |      S Nr}   1r~   )r   r   r   r   r   r   intr   s     r5   _perform_durationzCmfGanttTask._perform_duration   sU    &&!!D$:$::S@cl##GCL8#D3xrR   c                     | j                   j                  ry | j                   | j                  z  dz  }t        |      j	                  t        d      t
              }t        |      S r   )r   r   r   r   r   r   r   r   s     r5   _perform_workzCmfGanttTask._perform_work   sQ    ??""oo 6 66<cl##GCL8#D3xrR   c                    | j                   j                  s| j                  j                  ry| j                         }t	        j
                  t	        j                  t        |j
                  xs d                  }t        j                  j                  |      }| j                   |k\  ry|j                  | j                   j                  | j                  j                        }t        |      dk7  r/|j                  | j                   j                  |      }||z  dz  }nd}|dkD  rd}t        |      j                  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(2C2C2Hq.IJKkkoob!   C' ( ; ;D<Q<Q<W<WY]YoYoYuYu v$%*!)!<!<T=R=R=X=XZ]!^14IICO  #c!"&'00
0S3xrR   c                     | j                   j                  ry| j                   j                  dk(  rDg ddd| j                   gdd| j                  gg}t        j
                  j                  |      }|ryy)	NTrY   rZ   r   r[   r"   r]   F)r   has_child_tasksre   r"   r'   r   sget)rP   _filterhas_childrens      r5   r   zCmfGanttTask.has_child_tasks   ss     99$$99!!%99 , $		24-G
 "..3373CLrR   c                    |sy d}|}|r|S | j                   dk(  r| j                  rd}d}n| j                  r}d}| j                  j                  }| j                  dk(  r||k7  rd}|}d|d}n=| j                  dk(  r||kD  rd}|}d	|d}n| j                  d
k(  r||k  r
d}|}d|d}d| d|d}|rC|sAd| 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   sY   %!!%%2t7J7JE nD&&J!66<<N((I5.N:Z-GW_G`a
**i7N^<[->~h>WX
**j8^n=\-<^H<UV
.zl ;DDRS[C\^D ,QRVR[R[R`R`Qaadeienenesesdttvw{v||}~Dd$'rR   c                    |sy d}|}|rd}| j                   dk(  r| j                  r|sd}d}n| j                  rd}| j                  j                  }| j                  dk(  r||k7  r|r||k  rJd}|}d|d}n?| j                  dk(  r||kD  r|sd}|}d	|d}n| j                  d
k(  r||k  r
d}|}d|d}d| d|d}|rG|sE|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  sw   %"'$$	1d6I6IR]E nD''J!77==N))Y6>^;["n~&E E#1L#QR`aiQj!kJ++y8^n=\ep-D^T\D]^
++z9n~>]-B>RZB[\
.zl ;JJXYaIbdD , qQRVR[R[R`R`Qaadeienenesesdttvw{v||}~Dd$'rR   c                    d\  }}}| j                         r\| j                  j                  dk7  rC| j                         }|j                  | j	                                |j                         \  }}}|}| j                  dv r#| j                  }|r|rt        ||      }n|xs |}|}| j                  dv r#| j                  }|r|rt        ||      }n|xs |}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   re   load_fieldsrd   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  s    JZF/1F&&(TYY-C-CG[-[ $ ; ; =))$*B*B*DEM^MtMtMvJ 35J($$(>>33K1!+/AB)?-?*%%)@@55L 3"<1DE+B/B!00N2NL.88rR   c                    dx}x}}| j                   sy| j                         D ]  }|j                  dv rE|s|j                  j                  }n,|j                  r t        ||j                  j                        }|j                  dv r&|s|j                  j                  }|j                  r|j                  rt        j                  j                  |j                         |j                  j                  t        |j                               }|}n|j                  rt        ||j                  j                        }|j                  rct        j                  j                  |j                         |j                  j                  t        |j                               }t        ||      }|j                  dv rE|s|j                  j                  }n,|j                  r t        ||j                  j                        }|j                  dv r#|s|j                  j                  }|j                  r|j                  rt        j                  j                  |j                         |j                  j                  t        |j                              }|}n|j                  rt        ||j                  j                        }|j                  rbt        j                  j                  |j                         |j                  j                  t        |j                              }t        ||      }|j                  r1|s|j                  }n"|j                  rt        ||j                        }|j                   s\|j!                         \  }}}	|s|}n|rt        ||      }|s|}n|rt        ||      }|s|	}|	s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   rs   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  sY     7;::l^###88: H	LJ..2II"","A"A"G"GK44"%k:3R3R3X3X"YK//3JJ"","B"B"H"HK!00Z5U5U/5/A/A/V/V&446&<<BB !:!:;;0,
 ';55"%k:3S3S3Y3Y"ZK!00/5/A/A/V/V&446&<<BB !:!:;;0,
 '*+7K&L//3II##-#C#C#I#IL55#&|Z5U5U5[5[#\L..2HH##-#B#B#H#HL!00Z5T5T060B0B0W0W&446&;;AA
 9 9:1-
 (=44#&|Z5T5T5Z5Z#[L!00060B0B0W0W&446&;;AA
 9 9:1-
 (+<9N'O((%%/%>%>N..%(9R9R%SN))EOEhEhEjB1B""0K#"%k>"BK##2L$#&|_#EL%%6N&%(9J%KNQH	LT L.88rR   c                     t        | dd      ry d| _        | j                         \  | _        | _        | _        | j                         \  | _        | _        | _	        y )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  s^    47?,0)&&( 	_"D$?A^ ))+ 	_"D$?A^rR   c                    | j                   r| j                  ryt        j                  j	                  | j                         | j                   j                  | j                  j                  | j                  j                  xs |      }|| _        n3| j                   j                  r| j                  j                  rd| _        | j                  j                  r| j                  d||       y y )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 2 G G++---33,,22#'>>#7#7#M;M	 !H ! #4D""&&4+A+A+E+E"#D))..BTH` / b *rR   c                 X   | j                   ri| j                  r]t        j                  j	                  | j                         | j                   j                  | j                  j                        | _        y | j                   j                  r| j                  j                  rd| _        y y y Nr   )	r    r!   r'   r   r   r   r   actual_durationr   rU   s    r5   _calc_actual_durationz"CmfGanttTask._calc_actual_duration  s    !!d&=&=#)#5#5#J#J""$d&<&<&B&BDD[D[DaDa$cD ##''D,C,C,G,G#$D  -H'rR   c                 H   t         j                  j                  | j                         | j                  j
                  t        | j                               }| j                  |||      }| j                  dk(  r'| j                  r| j                  |kD  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"8">">TEXEXAY@Y[  88MUEP 9 R &&)3..43M3MP`3`#99rR   c                     t         j                  j                  | j                         | j                  j
                  t        | j                              }| 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  sk      ++@@ $"7"7"="=s4CVCV?WY !::.OWGR ; T ! rR   c                 L   | j                   j                  s| j                   dk(  rZ| j                  j                  sd | _        y | j
                  r| j
                  | _        y | j                  r| j                  | _        y | j
                  j                  r| j                  j                  ry | j
                  r/| j                  s#| j                  ||      | _        |rd | _        ny | j                  rJ| j
                  s>| j                  |      | _        | j                  dk(  r| j                  |      | _        y | j                  dk(  rX| j                  dk(  rH| j                  r;t        d| j                  j                   d| j                  j                   d       y y y y )	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99)))-& 	 ((-1-B-BD*  ++,0,B,BD)  ((T-C-C-K-K  )?)?%)%A%A8al%A%mD"(,% !!$*?*?$($?$?K$?$XD!))Y6)-)E)ER])E)^& $$	1d6P6PT]6]bfbubu)$))..)9TYY^^<L  MD  E  F cv6]1rR   c                 Z   | j                   j                  s| j                   dk(  rd | _        y | j                  j                  r| j                  j                  ry | j                  r\t        j
                  j                  | j                         | j                  j                  t        | j                               | _        y | j                  r]t        j
                  j                  | j                         | j                  j                  t        | j                                | _        y y 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.E.E.M.M!!&,&8&8&M&M""$d&<&<&B&BCH\H\D]'_D# ""%+%7%7%L%L""$d&=&=&C&Cc$J^J^F_E_&aD" #rR   c                    | j                   dk(  r| j                  j                  r| j                  j                  r| j                  dk7  ryt	        j
                  | j                  | j                  z  dz        }t        |d      }| j                  j                  s|| j                  kD  r|| _        | j                          yyyyy| j                   dk(  r| j                  j                  r| j                  j                  r| j                  dk7  ryt	        j
                  | j                  | j                  z  dz        }t        |d      }| j                  j                  s|| j                  kD  r|| _        | j                          yyyyyy)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  sb    $$0++0K0KPTP_P_cdPd#zz$*:*:T__*Ls*RS"<5''//<$BVBV3V+7D(==? 4W	 Qe0K+ &&/9++0K0K0W0W\`\w\w{|\|#zz$*:*:T=X=X*X[^*^_"<5''//<$BVBV3V+7D(==? 4W	 ]}0W+ :rR   c                 X   | j                   sy| j                  dk(  ry| j                  dk(  ry| j                  dk(  r| j                  dg      }|syt        |      }d}|D ]X  }|r7|j                  |j                  k(  r||j
                  j                  xs dz  }<||j
                  j                  xs dz  }Z ||z  }n| j                  dk(  r| j                  j                  d	k(  r5t        j                  j                  g d
dd| j                  ggddg      }n0t        j                  j                  dd| j                  gddg      }|syd}d}	|D ]  }|r|j                  |j                  j                  k(  r|j                  j                  ddg       ||j                  j                  j                  xs dz  }|j                  j                  j                  dk(  s|	|j                  j                  j                  xs dz  }	||j                  j                  xs dz  }|j                  j                  dk(  s|	|j                  j                  xs dz  }	 |	|z  dz  }n | j                  dk(  ry| j                  dk(  ry| j
                  k  r|| _        yy)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  rs   lenrb   r  r   r   re   r'   CmfTaskrf   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    ##$$0$$7&&,6!%!?!?HYGZ!?![%01K"#' H(QTT5J5M5M-M'+@+P+P+V+V+[Z[[''1+<+<+B+B+GaG'	H
 #6"C&&*:: yy%%)==%~~223($		: 12FG  3  I  &~~22=#tyy:Y;OQe:f  3  h "#$%!! 	Q(QTT5J5O5O5R5R-R)..::<PRf;gh&*?*D*D*W*W*]*]*babb&,1188DDP-1F1K1K1^1^1d1d1ihii-&!*>*>*D*D*II&xx++x7-1E1E1K1K1PqP-	Q #8:L"Ls"R&&(2&&)3"55#6D  6rR   c                 N   | j                          | 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                  |kD  r|| _        n| j                  dk(  rBt        j                  j                  dd| j                  gg d	      }d }d }|D ]  }|j                  j                  j                  j                  }|rW|j                   rK|j                  j"                  j$                  }t        j&                  j)                  |||j                         }|s|rt        ||      n|} d }| j+                         }|r|j                  j-                         }	|	r|	}n| j                  r| j                  }|r|rt        ||      | _        nJ|s|rF|xs || _        n:| j                  r| j                  | _        | j                  r| j                  | _        | j                  ra| j                  rU| j                  | j                  kD  r<t/        d
| j                  j0                   d| j                  j2                   dd       | j                  ra| j                  rU| j                  | j                  k  r<t/        d
| j                  j0                   d| j                  j2                   dd       | j                  dk(  | _        | j                  r&| j                  j6                  r| j9                          | j;                  d       y )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'   rg   rf   r   ri   r3   r   r   r,  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  s   $$&$$(JJ,,1F1F,0,A,A)(,D%$$	1$($=$=D!&&)3#88((T-G-G#&t'@'@$B\B\#] )>)>$BWBWZjBj(8%&&*4#88((T-G-G#&t'@'@$B\B\#] )>)>$BWBWZjBj(8%&&)3!3388!43z 9 L !MH+ f)22@@RRXX;#<#<*33;;DDH"("4"4"I"I(T_alazaz"{KGTC{$CZeMf $(  $ ; ; = *;*L*L*Q*Q*S'*+B(++'+'A'A$!5(+M;O(P%"6(5(M9M%))(,(B(B%))(,(B(B%%%$*?*?DDYDY\`\v\vDv)$))..)9TYY^^<L  MN  O  W[  \%%$*?*?DDYDY\`\v\vDv)$))..)9TYY^^<L  MV  W  _c  d0 &*%>%>)%K"  T%:%:%E%E002		D	!rR   c                 X   g }| j                   j                  dk(  ry | j                         r@| j                         }|j                  | j	                                |j                  |       dd| j                   gg dg}t        j                  j                  |dg      }|r|D cg c]"  }|j                  j                  j                  $ }}dd| j                  gdd	|gg}t        j                  j                  || j	                               }|j                  |       |S c c}w )
NrY   ri   r  )r_   r  r`   ra   r\   r"   task_idrc   )r   re   rW   r   rd   appendr'   rg   rf   ra   r   rb   r"   r   rk   )	rP   parent_gantt_tasksr   r   additional_parents_relationsrp   additional_parents_tasks_idsadditional_parents_filteradditional_parentss	            r5   _get_parent_gantt_tasksz$CmfGanttTask._get_parent_gantt_tasks)  s1   99!!%99&&( $ ; ; =))$*B*B*DE%%&78 dii(C
 (.'?'?'D'DGMVK (E (Y$'Lh+iSCKK,=,=,@,@+i(+i3,D">?)% "(!4!4!9!9AZAEAYAYA[ ": "]%%&89!! ,js   ('D'c                 \   | j                   j                  r@| j                   j                  j                  r | j                   j                  j                  S | j                  r)t        j                  | j                        j                  S t        j                  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  sx    99  TYY%:%:%C%C99((111??((9BBB!!%%+;ZL%QQrR   c                    d }d }g d}| j                  |d      }|D ]r  }|j                  | j                  k(  r|j                          |j	                  | j
                  j                  d      |_        d |_        |j                  r|j                          n|j                  d       |j                          |j                          |j                          |j                  d       |s|j
                  j                  }n t!        ||j
                  j                        }|j                  r9|s|j                  j                  }n t#        ||j                  j                        }| j	                  |       | j%                  |       u | j&                  r0| j(                  r$| j
                  rd | _        | j                          y |r|| _        |r|| _        | j+                  d       y )	N)r   !=TTrl   rm   r   r   r   r-  r   )r   )rs   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   rl   child_tasks
child_tasks         r5   rK  z/CmfGanttTask._calc_sched_period_for_child_tasksO  s    .
44
_c4d% $	MJ%%2224.8.Q.Q#'#8#8#<#<(, /R /
+ 04
,--AAC1141@((*55788:$/##-#>#>#D#D #&'79T9T9Z9Z#[ ++((2(D(D(J(J%(+,=z?[?[?a?a(b%))9I)J**:K*LI$	ML >>d11d6K6K%)D"##%(8% ):&%%%>rR   c           	         | j                  | j                  j                  |       | j                          | j                  r| j                  j                  r| j
                  rr| j
                  | j                  k  rY| j
                  | _        t        d| j                  j                   d| j                  j                   d| j
                  dd       | j                          y d }| j                  r5| j                  r)| j                  sd | _        | j                  d|       d	}n| j                  d
       d}| j!                  |       y )Nr   r   u/   Предупреждение: В задаче "r   u2   ) дата начала перемещена на r   ub   , так как была позже даты ограничения дочерней задачи.Tr  
start_dater   durationchanged_field)r   r   rJ  r   r   r   r   r   r   r   rK  r   lock_sched_finish_dater   r  r   _calc_resourcesrP   r   rW  s      r5   r/  z,CmfGanttTask._do_sched_start_date_is_changed  s3   %%T5J5J5N5N\g%h$$&D$9$9$=$=))d.H.H4K`K`.`(,(B(B%KDIINNK[[^_c_h_h_m_m^n oNNRNhNhiqMr s~ @ 335 M""t'<'<TE`E`)-&'';'O ,))4)H *  } =rR   c                    | j                  | j                  j                  |       | j                          d }| j                  r_| j
                  sS| j                  |       d}| j                  rG| j
                  j                  r1| j
                  r%| j                          n| j                  d       d}| j                  s| j                  |       y y )NrR  r  rS  TrT  rU  rV  )r   r   rJ  r   r   r   r  r   r   rK  r   rY  rZ  s      r5    _do_sched_finish_date_is_changedz-CmfGanttTask._do_sched_finish_date_is_changed  s    &&d6L6L6P6P^i&j$$&t'<'<###<(M##(=(=(H(HTMbMb779%%t%D&M##  } = $rR   c                    | j                  | j                  j                         | j                  | j                  j                         | j                  d       | j                  r| j                          | j                  d       y )NrI  TrT  rU  rV  )	r   r   rJ  r   r   r   r   rK  rY  rU   s    r5   _do_sched_dates_is_changedz'CmfGanttTask._do_sched_dates_is_changed  ss    %%T5J5J5N5N%O&&d6L6L6P6P&Q!!4!@335:6rR   c                    |j                   r%| j                   r|j                   | j                   k  s1|j                  r| j                  r|j                  | j                  kD  rpd}t        |j                  |j                  j
                  |j                  j                  | j                  j
                  | j                  j                               y y y y )Nu   Задача "{}" ({}) вышла за диапазон плановых дат родительской задачи "{}" ({}))r   r   r   formatr   r   r   )rP   rP  msgs      r5   %_alert_child_task_outside_sched_datesz2CmfGanttTask._alert_child_task_outside_sched_dates  s    ((T-B-B//$2G2GG,,1G1G0043I3II TCcjj!5!5z7K7KTYY^^]a]f]f]k]klm J 2H,rR   r8     )	only_onceonly_once_argspriorityc                 "   t         j                  j                  |       }|sy |j                         }|j	                  |       t         j                  j                  ||      }|sd}|j                  d||       |j                  d       y )Nrb   rb   r#   T)deferredrP  ignore_child_taskr-  )r'   r   r(   rd   r   from_sched_dates_of_child_tasksr/   )r8  child_task_idrk  r   r#   rP  s         r5   #from_sched_dates_of_child_tasks_jobz0CmfGanttTask.from_sched_dates_of_child_tasks_job  s     ""&&'&2))+ ((,,f,M
 $,,dzev,w		D	!rR   c                 F
   |s]| j                   j                  dk(  rDt        | j                  | j                  j
                  |j                  j
                  |d       y| j                  r|r|s| j                  |       y|
t               }| j                  j
                  |v r<t        d| j                   j                   d| j                   j                   dd	       |j                  | j                  j
                         d}d}|s|nd}|s|nd}d
g dg dg}	| j                  |	d      }
|
D ]  }|r|j                  |j                  k(  r|j                  r/|s|}n*|j                  s|}n|j                  |j                  kD  r|}|j                  sg|s|}l|j                  s|}{|j                  |j                  k  s|} |r|j                  }|r|j                  }|s5|r3|j                  r'|j                  s|j                  |k  r|j                  }|s5|r3|j                  r'|j                  s|j                  |kD  r|j                  }d}d}| j                   r|rd|j                   j                   d|j                   j                   d}| j                   j
                  }| j"                  dk(  r||k7  rd|d}n8| j"                  dk(  r||k  rd|d}n| j"                  dk(  r||kD  rd|d}nd}d}| j$                  r|rd|j                   j                   d|j                   j                   d}| j$                  j
                  }| j&                  dk(  r||k7  rd|d}n8| j&                  dk(  r||k  rd|d}n| j&                  dk(  r||kD  rd|d}nd}|rH|xs |}t        d| j                   j                   d| j                   j                   d| d| d	d	       || _        || _        | j                  j(                  s| j                  j(                  r| j+                  dd        | j-                          | j/                         }|rt0        j3                         5  |D ]g  }|j5                  | j7                                |j9                  | |!       |j;                          |j=                          |j?                  d"d#       i 	 ddd       |jA                  | j                  j
                         y# 1 sw Y   /xY w)$u  
        Обновляет плановые даты родительской задачи.
        Плановая дата начала = самая ранняя плановая дата начала всех подзадач
        Плановая дата окончания = самая поздняя плановая дата окончания всех подзадач

        Args:
            child_task (optional): Defaults to None
                измененная дочерняя задача, которая еще не сохранена.
            ignore_child_task (bool, optional): Defaults to False
                игнорировать дочернюю задачу при обновлении дат родительской задачи.
        rY   )r8  rm  rk  kwargsNr  r   u   ) невозможно обновить даты из-за обнаруженного цикла обновления дат задач связями Дополнительный родитель/Дополнительная дочерняя задача.Tr   OR)r   rE  N)r   rE  NrF  ")r   r   r   r   r   r   r   r   r   r   r   r   uU   Конфликт планирования: В родительской задаче "u   ) ограничение "u<   " конфликтует с дочерней задачей r   )r   r   )pathF
user_inputr&   )!r   re   schedule_deferred_jobrn  rb   r   r   rb  setr   r   r   addrs   r   r   r   r   r   r   r   r   rN  r?  r-   disable_aclr   rd   rl  rL  rM  r/   remove)rP   rP  rk  ru  rj  min_start_datemax_finish_dateschild_task_with_min_startchild_task_with_max_finishrl   gantt_tasksr2   r   conflict_child_task_min_startr   conflict_child_task_max_finishr   conflict_child_taskr:  r   s                       r5   rl  z,CmfGanttTask.from_sched_dates_of_child_tasks  sf    DII226JJ!88#ww}}%/]]%8%8): >> "3:::F<5D77==D )$))..)9TYY^^<L MB B JNO6GJT!7HZd" ,-


 44
_c4d% 	@Jjmmz}}<**00:-4EE4>12CCjFaFaa4>1++11;.5GG5?23EE
HdHdd5?2)	@, %6GGN%9KK!n009T9T00>A'99N!&6//
8T8T//2BB)::
(,%$$/01J1O1O1T1T0U V22K2P2P2U2U1VVW.Y)#'#<#<#B#B ))Y6&*>>GH\]eGfg
++y8&)==>?ST\>]^
++z9&)==<=QRZ<[\
04-)-&%%*:012L2Q2Q2V2V1W X33M3R3R3W3W2XXY/[*$($>$>$D$D!**i7(,AAMNcdlMmn
,,	9(+@@DEZ[cDde
,,
:(+@@BCXYaBbc
15."?"aCa 99>>*#diinn-==WXbWc dTTgShhikrvx !/!1  ++t/E/E/P/P%%RV%W 	**, "99;$$& 	M); M%%11$2J2J2LM%EE! F  &335%@@B%**et*LM	M 	DGGMM"	M 	Ms   ;A-TT c                    | j                         }|rt        j                         5  t               }|j	                  | j
                  j                         |D ]b  }|j
                  j                  |vs|j                  | ||       |j                          |j                          |j                  dd       d 	 ddd       yy# 1 sw Y   yxY w)uq  
        Обновление дат начала и окончания родительской задачи и доп родительских задач.
        Передает дочернюю задачу (self), так как она еще не сохранена
        и родительская задача не может получить обновленные данные.

        Args:
            ignore_child_task (bool, optional): Defaults to False
                игнорировать дочернюю задачу при обновлении дат родительской задачи.
        )rk  ru  FTrv  N)r?  r-   r{  ry  rz  rb   r   rl  rL  rM  r/   )rP   rk  r:  ru  r2   s        r5   update_parent_task_sched_datesz+CmfGanttTask.update_parent_task_sched_datess  s     "99;$$& Ju'"4 	JJ!}}**$6"BB .?!% C 
 #002"==?"5DI	JJ J J Js   AC	5A	C		Cc                    | j                         }|D ]  }|j                  dk(  rt        d       | |   s$||   r| |   ||   k  s5|j                  dk(  r||   r| |   ||   kD  rt        d        y |j                  dk(  r||   r| |   ||   k  rt        d        y | |   ||<   |j                          |j	                  |        y )Nr   ^   Дата родительской задачи является зафиксированнойr   u   Предупреждение: Плановая дата начала дочерней задачи больше плановой даты начала родительской задачиr   u   Предупреждение: Плановая дата начала дочерней задачи меньше плановой даты начала родительской задачи)
date_field)r?  r   r   r/   _change_parent_start_date)rP   r  parentsr   s       r5   r  z&CmfGanttTask._change_parent_start_date  s   ..0!( 	S 55Bz{J)::)F$zJZ]noy]zJz$99ZGL]^hLiZ(+<Z+HH  ]  ^$99YFK\]gKhZ(+<Z+HH  ]  ^04Z0@!*-!&&(!;;z;R%	SrR   c                    | j                         }|D ]  }|j                  dk(  rt        d       | |   s$||   r| |   ||   kD  s5|j                  dk(  r||   r| |   ||   k  rt        d        y | |   }|j                  dk(  rB||   r=| |   ||   kD  r2t        d       |j                  r||j                  kD  r|j                  }|||<   |j	                          |j                  |        | j                  dk(  | _        y )Nr   r  r   u   Предупреждение: Плановая дата окончания дочерней задачи меньше плановой даты окончания родительской задачиr   u   Предупреждение: Плановая дата окончания дочерней задачи больше плановой даты окончания родительской задачи)r?  r   r   r   r/   _change_parent_finish_dater   r.  )rP   r  r  r   
date_values        r5   r  z'CmfGanttTask._change_parent_finish_date  s:   ..0!( 	I 66)Cz{J)::)F$zJZ]noy]zJz$::iGL]^hLiZ(+<Z+HH  i  j!*-
$::jHM^_iMjZ(+<Z+HH  i  j(>>:PaPwPwCw%6%L%L
0:!*-!&&(!<<ZH)	I* &*%>%>)%K"rR   c                 T   | j                          | j                  dv r*| j                  s%| j                  r| j                  | _        nd | _        | j                  dk(  r| j                  | _        n| j                  dk(  rN| j                  }| j                  r,| j                  r t        | j                  | j                        }|r|| _        n| j                  dk(  ri| j                  }| j                  r,| j                  r t        | j                  | j                        }|r]| j                  r| j                  |kD  rB|| _        n:| j                  r| j                  | _        | j                  r| j                  | _        | j                  r| j                  rU| j                  | j                  kD  r<t        d| j                  j                   d| j                  j                   dd	       | j                  rU| j                  | j                  k  r<t        d| j                  j                   d| j                  j                   d
d	       | j                  dk(  | _        | j                  rT| j                  j                   r>| j"                  r"| j$                  dk(  r| j&                  sd | _        | j)                          | j                  rH| j                  j                   r2| j                  dk(  r| j                  sd | _        | j+                          | j-                  d       y )N)r   r   r   r   r   r   r  r   u   ) нельзя указать Дату окончания больше зафиксированной у родительской задачиTr   u   ) нельзя указать Дату окончания меньше зафиксированной у дочерней задачиr-  )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rX  r   r   r   r   r\  r/  r/   )rP   r   s     r5   $_do_constrain_finish_date_is_changedz1CmfGanttTask._do_constrain_finish_date_is_changed  s   $$&%%)KK--$2H2H-1-C-C*)-D&%%2%)%?%?D"''94 $ : :))d.I.I$'(B(BDD_D_$`! ):&'':5 $ : :))d.I.I$'(B(BDD_D_$`! $*@*@DDZDZ]nDn):&))(,(B(B%))(,(B(B%!!**t/E/EHcHc/c-diinn-=S@P  Q_  `  hl  m**t/E/EHcHc/c-diinn-=S@P  QW  X  `d  e0 '+&@&@I&M#!!d&<&<&G&G""D,E,E,RW[WpWp(,%113  T%:%:%E%E..);@Z@Z)-&002		D	!rR   c                    | xr@ | j                   j                  xr( | j                   dk(  xr | j                  j                   }| xr= | j                   j                   xr$ | j                   xr | j                  j                  }|xr2 | j                  j                   xr | j                  | j
                  k(  }|s|s|rB| j                  j                   | j                  _        | j                  j                  d       | j                  dk(  r| j                  dk(  r| j                  j                  s| 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       |s@|s%| j
                  rd | _        | j!                  d       |s|s| j#                  d       y y y y )Nr   Tr-  r   u;   Конфликт планирования в задаче "r   u   ): невозможно изменить трудозатраты, если установлена опция "Фиксированные Ресурсы" и зафиксированы даты начала и окончания.r   u   ): невозможно изменить длительность, если зафиксированы даты начала и окончания.ua   Невозможно изменить плановую длительность, у задачи  (uZ   ) установлена опция "Фиксированная длительность".rH  rU  rV  )r   r   r   r  r   r   r/   r   r   r   r   r   r   r   r   rC   r  rY  )	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$2E2E2I2I  FdNaNaefNf  Fosoxox  pF  pF  lF--  Ad6I6I6M6M2M  ARVReRe  Ajnjsjs  kA  kA)|$))2H2H.H|TMcMcgkg|g|M|Vv)-)?)?%?DII"IINNTN* %%2t7Q7QU^7^11<<TE_E_EjEj&WX\XaXaXfXfWggjkoktktkykyjz {  $& WX\XaXaXfXfWggjkoktktkykyjz {n nuy{ yz~  {D  {D  {I  {I  zJ  JL  MQ  MV  MV  M[  M[  L\ \r ry}$ #+((-1D*'''6  ,4K$$:$> 5L+) #rR   c                 $    | j                          y rT   )r  rU   s    r5   _do_actual_duration_is_changedz+CmfGanttTask._do_actual_duration_is_changedJ  s      "rR   c                    t         j                  d| j                  j                   d| j                  j
                  j                          | j                  j                  ry | j                  dk  rPt        d| j                  j                  j                   d| j                  j
                  j                   dd       | j                  }|r|sd}|s*| j                  j                  d	k7  r| j                  | _        | j                          | j                  j                  xs d| j                  j                  xs dz
  }t         j                  d
| j                  j                   d| j                  j
                  j                   d| j                  j                  xs d d| j                  j                  xs d d| j                  j                   
       | j!                         r| j                  j                  d	k7  rt"        j%                         5  | j!                         }|j'                  | j)                                |j+                  |       |j-                  d       |j/                  d       d d d        |sB| j                  j0                  r+t2        j4                  j7                  | j                  |       y y y # 1 sw Y   NxY w)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_childr-  )gdebugrb   r   r   r   r  r   r   r   r   re   actual_myself_workr  rJ  r   rW   r-   r{  r   rd   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   	<TWW]]O:VZV_V_VdVdVjVjUklm##aXY]YbYbYgYgYmYmXnnqrvr{r{  sA  sA  sG  sG  rH  Hg  h  pt  u../"O499#9#9=Q#Q&*&6&6D#""$&&**/aD4D4D4H4H4MAN
	4TWW]]O:diinnNbNbMc d''+'7'7';';'@q&AAWX\XhXhXlXlXqpqWr  sA  BF  BR  BR  BX  BX  AYZ 	[ &&(TYY-C-CG[-[$$& 7$($?$?$A!!--d.F.F.HI!55jA!<<D<Q!&&&67  D$;$;$F$F!!DDTYYPZ[ %G7 7s   A%KKc                    | j                   j                  ry | j                   dk  r<t        d| j                  j                   d| j                  j
                   dd       | j                  dk(  r| j                  j                  r| j                  dk7  rwt        j                  | j                   | j                  z  dz        }t        |d      }| j                  j                  s|| j                  kD  r|| _        | j                          | j                         r| j                  j                  d	k7  r| j                   j                   xs d| j                   j"                  xs dz
  }t$        j'                         5  | j                         }|j)                  | j+                                |j-                  |       |j/                  d
       d d d        y y y # 1 sw Y   y xY w)Nr   r  r   ug   ) "Фактические Затраты" стал ниже нуля, выставляем в ноль.Tr   r  r}   rY   Frw  )actual_costr   r   r   r   r   r  r   r  r  r  r   r  r  rW   re   rJ  r   r-   r{  r   rd   from_child_add_costr/   )rP   r  
cost_deltar   s       r5   _do_actual_cost_is_changedz'CmfGanttTask._do_actual_cost_is_changedp  s   ##a)$))..)9TYY^^<L  Mt  u  }A  B$$0**t!/C#zz$*:*:T__*Ls*RS"<5''//<$BVBV3V+7D(==?&&(TYY-C-CG[-[**..3!8H8H8L8L8QPQRJ$$& 9$($?$?$A!!--d.F.F.HI!55jA!&&%&8	9 9 .\(9 9s    AGG'c                 r    | j                   j                  ry | j                  dk(  ry | j                  dk(  ry y )Nr	  r  )r  r   r  rU   s    r5   _do_actual_complete_is_changedz+CmfGanttTask._do_actual_complete_is_changed  s=    ''$$0 &&(2 3rR   c                     | j                   j                  xs d| j                   j                  xs dz
  }| j                  s| j                   | _        n| xj                  |z  c_        | j                  |       y )Nr   r  )r  rJ  r   r   r  r  )rP   r  r  s      r5   !_do_actual_myself_work_is_changedz.CmfGanttTask._do_actual_myself_work_is_changed  sk    --116Q4;R;R;V;V;[Z[\
##  $66D
*''9I'JrR   c                     | j                   j                  xs d| j                   j                  xs dz
  }| j                  s| j                   | _        n| xj                  |z  c_        | j                          y r   )actual_myself_costrJ  r   r   r  r  rP   r  s     r5   !_do_actual_myself_cost_is_changedz.CmfGanttTask._do_actual_myself_cost_is_changed  se    --116Q4;R;R;V;V;[Z[\
##  $66D
*'')rR   c                    | j                   j                  ry | j                  | j                   k7  r!| j                   | _        | j                          | j                  r| j                   | j
                  k  r| j
                  dz   d| j
                  dz   d}| j                   dz   d| j                   dz   d}| j                  rCt        d| j                  j                   d| j                  j                   d| d| d	d	
       nP| j
                  | _         |s=t        d| j                  j                   d| j                  j                   d| d       | j                          | j                         r| j                  j                  dk7  r| j                   j                  xs d| j                   j                  xs dz
  }t         j#                         5  | j                         }|j%                  | j'                                |j)                  |       |j+                          |j-                  dd	       d d d        |s|s|s| j/                  d       y y y y # 1 sw Y   %xY w)N<      ч    мr  r   u   ) нельзя запланировать меньше Трудозатрат, чем запланировано в подзадачах ( < ub   ). Увеличьте Трудозатраты или уменьшите их у подзадач.Tr   u   ) указано Трудозатрат меньше, чем запланировано в подзадачах. Выставили uo   . Если нужно уменьшить Трудозатраты, уменьшите их у подзадач.rY   r   Frv  workrV  )r   r   r  %_do_timetracker_sched_work_is_changedr   agregat_workrG   r   r   r   r   r  rW   re   rJ  r   r-   r{  r   rd   from_child_agregate_workrM  r/   rY  )	rP   from_sched_duration_changedr   r   r  r  r   r  r   s	            r5   _do_sched_work_is_changedz&CmfGanttTask._do_sched_work_is_changed  sF   ??""&&$//9*.//D'668 !2!22"&"3"3r"9!:#d>O>ORT>T=UUWX $2 56c$//B:N9OrR
?? 1$))..1ATYY^^DT U##-,c, @AA IMN '+&7&7DO-!$5diinn5ESHX Y99E GS#T U* 	""$&&(TYY-C-CG[-[//--2t7J7J7OaPJ$$& I$($?$?$A!!--d.F.F.HI!:::F!<<>!&&%4&HI (0KTg  v 6 Uh0K'I Is   A$I$$I-c                    | j                   j                  ry | j                   | j                  k  r| j                  rWt	        d| j
                  j                   d| j
                  j                   d| j                    d| j                   d	d       nX| j                  | _         t	        d| j
                  j                   d| j
                  j                   d| j                   d	       | j                         r| j
                  j                  d
k7  r| j                   j                  xs d| j                   j                  xs dz
  }t        j                         5  | j                         }|j                  | j                                |j!                  |       |j#                          |j%                  dd       d d d        y y y # 1 sw Y   y xY w)Nr  r   u   ) нельзя запланировать меньше Расходов, чем запланировано в подзадачах (r  uX   ). Увеличьте Расходы или уменьшите их у подзадач.Tr   u~   ) указано Расходов меньше, чем запланировано в подзадачах. Выставили ue   . Если нужно уменьшить Расходы, уменьшите их у подзадач.rY   r   Frv  )r   r   agregat_cost
const_costr   r   r   r   rW   re   rJ  r   r-   r{  r   rd   from_child_agregate_costrM  r/   rP   r  r   s      r5   _do_sched_cost_is_changedz&CmfGanttTask._do_sched_cost_is_changed  s   ??"" ??T...-diinn-=S@P Q#/s43D3D2E Fssz~@ #'"3"3-diinn-=S@P  QO  PT  Pa  Pa  Ob bA B C&&(TYY-C-CG[-[//--2t7J7J7OaPJ$$& I$($?$?$A!!--d.F.F.HI!:::F!<<>!&&%4&HI I .\(I Is   A$GGc                 v    | j                   r| j                  r| j                          y | j                          y rT   )r    r   r  r   rU   s    r5    _do_actual_start_date_is_changedz-CmfGanttTask._do_actual_start_date_is_changed   s+    !!d&:&:$$&&&(rR   c                     | j                   s)| j                  r| j                  r| j                          y | j	                          y rT   )r    r!   r   r  r   rU   s    r5   !_do_actual_finish_date_is_changedz.CmfGanttTask._do_actual_finish_date_is_changed  s3    %%$*A*AdFZFZ$$&&&(rR   c                    | j                   dk(  r| j                          y | j                   dv r| j                  r| j                          y | j                   dk(  r| j	                          y | j                   dk(  r| j                          y )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++- 	 &&*JJtOcOc335 	 &&(2++- 	 &&/9668rR   c                 >    | j                   r| j                          y y rT   )rC   r   rU   s    r5   _do_const_duration_is_changedz*CmfGanttTask._do_const_duration_is_changed  s     %%' rR   c                    | j                   r| j                          y g ddd| j                  gg}| j                  s t        j
                  j                  |      r| j                  d d       y d| _        | j                          y )Nr^   ra   r[   r   TrP  rk  r+  )
r   r   r   r   r'   rg   r   rl  r   r6  )rP   _additional_task_filters     r5   _do_is_manual_is_chagnedz%CmfGanttTask._do_is_manual_is_chagned   s{    >>%%' ID$)),'# ##v'?'?'D'DLc'D'd44X\4],5)88:rR   c                 v    | j                   j                  dk(  r | j                   r| j                  d       y y y )NrB   unitsrV  )rO   r   rY  rU   s    r5   _do_task_sched_type_is_changedz+CmfGanttTask._do_task_sched_type_is_changed.  s8    ##z1d6J6J  w 7 7K1rR   c                     | j                   rd| _        | j                  | _        y | j                  j                  | _        d | _        y Nr   )r.  r   r   r   defaultrU   s    r5   $_do_lock_sched_start_date_is_changedz1CmfGanttTask._do_lock_sched_start_date_is_changed2  s=    %%(1D%(,(=(=D%(,(A(A(I(ID%(,D%rR   c                     | j                   rd| _        | j                  | _        y | j                  j                  | _        d | _        y r  )rX  r   r   r   r  rU   s    r5   %_do_lock_sched_finish_date_is_changedz2CmfGanttTask._do_lock_sched_finish_date_is_changed:  s=    &&)2D&)-)?)?D&)-)C)C)K)KD&)-D&rR   c                 .   |sy | j                  g d       |j                  j                         }|j                  | j                                |j	                  | j
                         |j                  | j                         |j                  | j                         |j                          |j                  | j                         |j                  d       |j                  rp| j                  sd| j                  |j                   j"                  d      | _        | j                   j$                  r| j'                          |j)                  |        n*|j                  r| j                  rn|j+                  |        |j-                  d       y )N)r   r   r  r  r   r   Tr  rG  r-  )r   r3   r8   rd   r  r   r  r   r  r  r  r  r  r  r   r   r   r   r   r/  rb  rl  r/   rP   r   r   s      r5   add_child_task_to_parent_taskz*CmfGanttTask.add_child_task_to_parent_taskB  sH    
 	 (55::<%%d&>&>&@A224??C224??C--d.>.>?446--d.>.>?44D4I&&t~~$($A$A0AAGG$( %B %D! $$//446CCDI((T^^==dC.rR   c                    |sy | j                  g d       t        j                  d| j                  j                   d| j
                  j                  j                   d| j                  j                          |j                  j                         }|j                  | j                                |j                  | j                          |j                  | j                          |j                  | j                           |j#                          |j%                  | j                          |j'                          |j)                  | d       |j+                  d       y )N)r   r   r  r  z*remove_child_task_from_parent_task gt_id: r  z$, gt.actual_work to be substracted: T)rk  r-  )r   r  r  rb   r   r   r   r  r3   r8   rd   r  r   r  r   r  r  r  r  r  rl  r/   r  s      r5   "remove_child_task_from_parent_taskz/CmfGanttTask.remove_child_task_from_parent_taskg  s.   ST	<TWW]]O:VZV_V_VdVdVjVjUk l5595E5E5K5K4LN 	O (55::<%%d&>&>&@A22DOO3CD22DOO3CD--t/?/?.?@446--t/?/?.?@44699$RV9W.rR   c                 2   t         j                         5  | j                  j                  xs | j                  }|r| j                  |       | j                  j                  xs | j                  }|r| j                  |       d d d        y # 1 sw Y   y xY wrT   )r-   r{  r   r   r   r  rJ  r  )rP   
old_parent
new_parents      r5   _do_parent_task_is_changedz'CmfGanttTask._do_parent_task_is_changedz  s       " 	?))--C1C1CJ77
C))--C1C1CJ22:>	? 	? 	?s   A/BBc                 L    t        j                  j                  | dg|i | y )Nupdated)r'   CmfEventdo_event)rP   argsrq  s      r5   _do_event_savezCmfGanttTask._do_event_save  s       yB4B6BrR   c                      | |   j                   S rT   )	log_level)rP   
field_namer  rq  s       r5   _get_field_log_levelz!CmfGanttTask._get_field_log_level  s    J)))rR   c                 x	   | j                   rgd| _        d| _        | j                         rH| j                         }|j                  j                         }|| _        d| _        | j                          y | j                  j                  rd| _        | j                  j                  r| j                          y | j                  j                  r| j                          y | j                  j                  r| j                          y | j                  j                  r#| j!                          |s| j#                          y | j$                  j                  r| j'                          y | j(                  j                  r| j+                          y | j,                  j                  r| j/                          y | j0                  j                  r| j3                          y | j                  j                  r#| j5                          |s| j#                          y | j6                  j                  r| j9                          y | j:                  j                  r| j=                          y | j>                  j                  r| jA                          y | jB                  j                  r| jE                          y | j                  j                  r#| jG                          |s| j#                          y | jH                  j                  r#| jK                          |s| j#                          y | jL                  j                  s| j                  j                  r#| jO                          |s| j#                          y | jP                  j                  s| jR                  j                  r#| jU                          |s| j#                          y | jV                  j                  r| jY                          y | jZ                  j                  r| j]                          y | j^                  j                  r| ja                          y | jb                  j                  r| je                          | jf                  j                  r| ji                          | jj                  j                  r$| jm                          |s| j#                          y y y )Nr   r+  )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  r/  r   r\  r   r6  r   r   r  r   r  rC   r  r.  r  r  r  rX  r  rO   r  )rP   from_parent_changesr   r5  s       r5   _savezCmfGanttTask._save  s   ;;"#DDO**,$($?$?$A!*;*L*L*Q*Q*S'(?%,5)'')$$,,(1D%&&++-""--224""--224))..0&335**//1&&++-&&++-**//1??%%**,&335??%%**,!!,,113""--224$$//446  ++002&335!!,,113&335$$//43L3L3W3W446&335%%00D4N4N4Y4Y557&335>>$$))+))..0%%00557&&11668&&11668**//1&335 ' +rR   uS   Вычисление плановых работ по ресурсам задачиgantt_task_id)descriptionshow_bg_progressbarrd  re  rf  c           	      h   t         j                  d|         | y t        j                  j	                  |       }|sy |j                  |j                                dd|j                  gg dg}t        j                  j                  |dg      D ]/  }t        j                         5  |j                          d d d        1 t        j                  j                  dd|j                  gg d      }|sy |j                  j                  }|j                   j                  }t#        |j$                  j                        }t#        |j&                  j                        }t)        |      }	||z  |	z  }
|}d	}|	d
kD  r
||	z  }||	z  }t         j                  d|j                  j*                  j                   d|         |D ]'  }|}|d	kD  r||z  }d	}|j-                  |||||
d       ) t         j                  d|  d|j                  j*                  j                          y # 1 sw Y   xY w)Nz)calc_resources_job start. gantt_task_id: rh  r"   r[   history_typer[   planr  r\   r"   personr   r   rc  z4calc_resources_job start_res_assignment. task.code: z gantt_task_id: T)
assignment	work_leftrS  r3  r  
create_tthz'calc_resources_job end. gantt_task_id: z task.code: )r  r  r'   r   r(   r   rd   r   CmfTimeTrackerHistoryrf   r-   r{  deleteCmfTaskResAssignr   r   r   r   r   r   r  r   _plan_resource_days)r  r2   r   tthassignmentsrS  r3  rU  r  number_of_resourcesr  work_per_personwork_remainderr  r  s                  r5   calc_resources_jobzCmfGanttTask.calc_resources_job  sF    	
;M?KL ((,,,>
z==?@dJOO413//44G^L\4] 	C$$& 

 	 --228T:??:[:Z 3 \0066
 2288:44::;z,,223!+.$77""&99O!$77N	FzG[G[GaGaFbbr  tA  sB  C  	D% 	<J'I!^+	!"**j5>6@7B166: + <	< 	
9-U_UdUdUiUiUoUoTpqrI s   *H''H1	c           
         d }d }	|j                   j                  |j                         | j                  j                  |xr |j                               }
	 	 t        |
      }j                  j                  }d}||j                         k(  rt        |j                  |            }t        |j                  j                  |z
        }|dk  rzt        ||z        j                  t        d      t              }||z  |z
  }||z  }||k  r|}|j                  t        |            }|j                  t        |||z   |z  z               xs |j!                  dd	      }|rht"        j%                  |j&                  | j(                  ||d
t        |      d      }t*        j-                         5  |j/                  d       d d d        |s|}|"|j1                  |d      }||z   |kD  r||z   ||<   ||z  }t        |j                  t        d      t2                    dk(  r|}		 ||	fS # t        $ r!}t        t        |      d       Y d }~d }~ww xY w# 1 sw Y   xY w)N)rS  r   r3  Tr   r   r   r~      ;   )hourminuter  )r9   r"   rS  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  rS  r3  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(  s   
#,,66*//BSJN..J^J^CNCeS^ScScSe 7 g .>* xx~~HJ:??,,$S%<%<Z%HI
 !;!;!A!AJ!NOJQ$Z%%78AA'#,YfAgN(2U(:n'L$11I>)!* 66s:GN44SYqHquzGz9{5|}  l  BP  BX  BX  ^`  ik  BX  BlL22(//99-)!'">2'( 3  ((* +HHEH*+ +
+)9)=)=h)J&!$<<?UU1?BZ1Z$X.'I9%%gclZ%HIQN'8##g  ! .#a&--.@+ +s$   H/ 2I/	I8III%c           
           fd}|sy  j                   dk(  ry t        j                  d j                          dd j                  gg dg}t        t        j                  j                  |dg            d	kD  }|sTt        j                  j                  |d
g      D ]/  }t        j                         5  |j                          d d d        1  j                  j                  } j                  j                  }t!         j"                  j                        }	t!         j$                  j                        }
|
}|	}d}|0t        j&                  j                  dd j                  gg d      }t        |       |       }|
sd j$                  j(                  rN|sL j*                  s j                   dk7  r/d _         j"                  j,                  r j/                  d       d}|	sI j"                  j(                  r3|s1d _         j$                  j,                  r j1                  d       d}|r`t        j                  d j                          |r;t3        t        j4                  j6                  d j                  j                  i       y  j*                  r|	r|
s|	}
|
|	z  z  }n|
s|	}
|	s|
}	 j                   dk(  r	|
|	z  z  }nc j                   dk(  r|dk(  rO|
|	z  z  }nF 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kD  rd}|
}d}dkD  r
|
z  }|
z  }g }g }i }|D ]  }|}|dkD  r||z  }d} j9                  |||||||       \  }}|j;                  |       |j;                  |       |j=                         |_        |j=                         |_         tC        |dz        |_"        t        j                         5  |jG                          d d d         tI        |       _        tK        |       _        tC        tM        |jO                               |z  jQ                  t!        d      tR                     _        tC        |
       _         j                   dk(  rd|d v r| j"                  j                  k7  r j/                  d       |dk(  r}| j$                  j                  k7  rc j1                  d       nO j                   dk(  r3|d!v r;| j$                  j                  k7  r! j1                  d       n j                   dk(  r|d v r[| j"                  j                  k7  r j/                  d       |dk(  r+| j$                  j                  k7  r j1                  d       |dk(  r| j$                  j                  k7  r j1                  d       nn j                   dk(  r_|dk(  r+| j"                  j                  k7  r j/                  d       |d!v r+| j$                  j                  k7  r j1                  d       |r;t3        t        j4                  j6                  d j                  j                  i       t        j                  d" j                          y # 1 sw Y   xY w# 1 sw Y   lxY w)#Nc                      j                   ry dk(  ryj                  syj                  sj                  syj                  rj                  rj                  syy)NTr   F)r   r   r   r   r   )r  rP   s   r5   check_exit_conditionsz;CmfGanttTask._calc_resources.<locals>.check_exit_conditionsg  sS    ##"a'((&&t~~$//$:M:MrR   rB   z&_calc_resources start. gantt_task_id: r"   r[   r  --r\      r  rc  r  rD   r   T)r  )r  z4_calc_resources exit_conditions_met. gantt_task_id: r  rp  rJ   rH   rU  r  r  rF   i@8  )r  r}   r   r~   )r  r  )r  rU  z'_calc_resources finish. gantt_task_id: )*rO   r  r  rb   r   r  r'   r   rh   rf   r-   r{  r  r   r   r   r   r   r   r  r   r   r   r   r  rx  r   r	  r  r9  r  
date_startdate_endr   r  r/   r   r   sumvaluesr   r   )rP   rW  r  r+  _tth_filter	havy_taskr  rS  r3  rU  r  initial_workinitial_durationr  	do_returnr  r  start_times	end_timesr  r  r  r  r  r  s   `                       @r5   rY  zCmfGanttTask._calc_resourcese  s   	 :-	8	BC $		257 44::+W[V\:]^acc	3388UcTd8e !((* !JJL! !! **00
,,224..445t,,-# 1166xtyy>Y>^ 7 `K "+.)+	 ++I~~!5!59K!K&'#&&1166t6TI D//33IDO))..4.HIGGJ477)TU%f&9&9&L&LVegkgngngtgtUuv>>H_(;;E ##'BB,??%%7 J.!H_0CCE%%);; F*!H_0CCE"g-*1L#&99D%%);; J.#&99D5LX&I""&99O!$77N	% 	"J'I!^+	!"#'#;#;J	S]<GP`KT} $< $V J z*X&$.OO$5J!"*--/J"53;/J$$& "!" "!	"& !$K 0!$Y!3'7'>'>'@#AE#I"S"ST[\_T`kx"S"yzd)>1 11#t':':'@'@@6646P G+@U@U0U22t2L!!%77 554??#8#8822t2L!!%77 11#t':':'@'@@6646P G+@U@U0U22t2L
*4??#8#8822t2L!!%@@&+;t?R?R?X?X+X22t2L 55,$//J_J_:_..4.H!&"5"5"H"HRacgcjcjcpcpQqr	9$''CDM! !D" "s   :Z4?[4Z>	[	c                     | j                  | j                                | j                  xs | j                  }|r| j	                  |       y y rT   )r   rd   r   r   r  rP   r"   s     r5   task_copy_hookzCmfGanttTask.task_copy_hook  sE    1134!!7T%7%7..v6 rR   c                     | j                  | j                                | j                          | j                  d|       | j	                          | j                  d       y )Nr  )rW  r  Tr-  )r   rd   r,   rY  rN  r/   )rP   r  s     r5   task_resources_changed_hookz(CmfGanttTask.task_resources_changed_hook  sR    1134!7L**,		D	!rR   c                    |sy | j                  | j                                | j                          |r=| xj                  |z  c_        | xj                  |z  c_        | j                  d       y | xj                  |z  c_        |d k7  r| j                  |z   | _        | j                  d       | j                  d       y )NTr-  r  )r   rd   r,   r  r  r/   r  r  )rP   r  r  from_tth_restores       r5   timetracker_add_work_hookz&CmfGanttTask.timetracker_add_work_hook  s    1134!
*##z1#III%:-%*.*A*ADV*VD'...E 			D	!rR   c                     | j                  | j                                | j                          | xj                  |z  c_        | j	                          | j                  d       y NTr-  )r   rd   r,   r  r  r/   r  s     r5   timetracker_add_cost_hookz&CmfGanttTask.timetracker_add_cost_hook3  sP    1134!:-..0		D	!rR   c                    | j                  | j                         ddgz          d}| j                  j                  rJ| j                  j                  j                  j
                  dk(  r| j                  j                  | _        d}| j                  r-| j                  j                  | _        | j                          d}|r| j                  d       y y )Nry   task.parentF
CmfProjectTr-  )
r   rd   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37Y[h6iij	99		 0 0 6 6 A A\ Q99++DLI!%!8!8D$$&IIII% rR   c                 $    | j                          y rT   )r  rU   s    r5   r  z2CmfGanttTask._do_timetracker_sched_work_is_changedJ  s    ""$rR   c                 J   |r|j                   dk(  r| j                  s| j                  | j                                | j	                          | j                  j                          | j                          | j                          | j                          | j                  d       y |r|j                   dk7  r|r|j                   dk(  r| j                  | j                                | j	                          | j                  j                          d| _        | j                          | j                          | j                          | j                          | j                  d       | j                          y |r|j                   dk(  r|r|j                   dk7  r| j                  | j                                | j	                          d | _
        d| _        | j                          | j                          | j                  d       | j                          y y y y y )NIN_PROGRESSTr-  r  r}   r   )r  r    r   rd   r,   set_nowr  !_pass_actual_dates_to_sched_datesrN  r/   r!   r  r  r  r  )rP   
old_status
new_statuss      r5   task_status_is_changed_hookz(CmfGanttTask.task_status_is_changed_hookM  s    *00MA$J`J`T5578##%""**,113224..0III%*00H<:#9#9X#ET5578##%##++-#&D 224//1224..0III%557*00H<:#9#9X#ET5578##%&*D##$D 224//1III%557 $FJ =:rR   c                    | j                  | j                                | j                  st        dd       | j	                          | j
                  s	 | j                  j                  | _        | j                  j                  | _	        | j                  j                  s| j                  j                  rS| j                          | j                          | j                          | j                          | j                  d       y	y	y	# t         $ rP}t        d| j                  j"                   d| j                  j$                   dt'        |       d       Y d	}~y	d	}~ww xY w)
u  
        Задача находится в списке с включенной опцией "Выставлять даты списка в плановые даты задач"
        Меняем плановые даты на даты из списков
        u?   У гант-задачи нет ссылки на задачу.Tr   r-  u(   Плановые даты задачи "r   u   ) не изменились                            при попытке выставления дат от спринтов из-за ошибки: "rs  N)r   rd   r   r   r,   r   plan_start_dater   plan_end_dater   r   r^  rN  r  rH  r/   CmfAbortErrorr   r   r  )rP   r   s     r5   task_plan_dates_is_changed_hookz,CmfGanttTask.task_plan_dates_is_changed_hookx  sK   
 	1134yyW_cd!##K(,		(A(A%)-)@)@&((33t7M7M7X7X335668779,,.III- 8Y	 $ ! KDTYY^^DTTWX\XaXaXfXfWg h@ AD  EF  AG  @H  HIJ K KKs   B4D 	E&AE!!E&c                     | j                  | j                                | j                          | j                  d       y rB  )r   rd   rH  r/   rU   s    r5   task_logic_type_is_changed_hookz,CmfGanttTask.task_logic_type_is_changed_hook  s3    1134  "		D	!rR   c                     | j                  | j                                | j                  j                  | _        | j                  j                  r| j                          y y rT   )r   rd   r   r   r   r/   rU   s    r5    task_parent_task_is_changed_hookz-CmfGanttTask.task_parent_task_is_changed_hook  sH    11349900&&IIK 'rR   c                     | j                  | j                                | j                  j                  | _        | j	                          y rT   )r   rd   r   r   r/   rU   s    r5   "task_gantt_project_is_changed_hookz/CmfGanttTask.task_gantt_project_is_changed_hook  s4    1134!YY44		rR   c                     | j                  | j                                | j                  r!d | _        d| _        | j	                  d       y y )Nr+  Tr-  )r   rd   r   r   r/   rU   s    r5   $task_has_child_tasks_is_changed_hookz1CmfGanttTask.task_has_child_tasks_is_changed_hook  sE    1134$$(,D%(1D%III% %rR   c                     | j                  | j                                | j                  d d       | j                          | j	                          | j                  d       y )NTr  r-  )r   rd   rl  rL  rM  r/   rU   s    r5   *additional_children_relations_changed_hookz7CmfGanttTask.additional_children_relations_changed_hook  sS    1134,,PT,U'')		D	!rR   c                 h    | j                   j                  rd| _         | xj                   |z  c_         y r   )r  r   )rP   r  s     r5   r  z CmfGanttTask.from_child_add_work  *    ## DJ&rR   c                 h    | j                   j                  rd| _         | xj                   |z  c_         y r   )r  r   r  s     r5   r  z CmfGanttTask.from_child_add_cost  rc  rR   c           	         | j                   j                  rd| _         | xj                   |z  c_         | j                  sG| j                   | _        | j                  j                  xs d| j                  j
                  xs dz
  }n| j                   | j                  k  se| 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                  xs d| j                   j
                  xs dz
  }| j                         r| j                  j                  dk7  rt        j                         5  | j                         }|j                  | j                                |j                  |       |j                          |j!                  dd	       d d d        y y y # 1 sw Y   y xY w)Nr   r  r  r  u;   Превысили План на Трудозатраты ( <= +   ) в родительской задаче ub   . Увеличьте в ней план или введите меньше Трудозатрат.Tr   rY   Frv  )r  r   rG   r   rJ  r   r   r   rW   re   r-   r{  r   rd   r  rM  r/   )rP   r  r  r   r   s        r5   r  z%CmfGanttTask.from_child_agregate_work  s   $$ !DZ'"//DO//--2t7J7J7OaPJ$$7"&"3"3r"9!:#d>O>ORT>T=UUWX $2 56c$//B:N9OrR
WXdWeeijtiu vGGKyyk R~ GKL ++//419J9J9N9N9SRSTJ &&(TYY-C-CG[-[$$& I$($?$?$A!!--d.F.F.HI!:::F!<<>!&&%4&HI I .\(I Is   6A$G%%G.c           	         | j                   j                  rd| _         | xj                   |z  c_         | j                  s| j                   | _        nN| j                   | j                  k  s5t	        d| j                    d| j                   d| j
                   dd       | j                         r| j
                  j                  dk7  r| j                   j                  xs d| j                   j                  xs dz
  }t        j                         5  | j                         }|j                  | j                                |j                  |       |j                  d	       d d d        y y y # 1 sw Y   y xY w)
Nr   u1   Превысили План на Расходы (rf  rg  u[   . Увеличьте в ней план или введите меньше РасходовTr   rY   r-  )r  r   r  r   r   r   rW   re   rJ  r   r-   r{  r   rd   r  r/   r  s      r5   r  z%CmfGanttTask.from_child_agregate_cost  sV   $$ !DZ'"//DO$$7MdN_N_M``deietetdu vGGKyyk  Rmn $& &&(TYY-C-CG[-[++//419J9J9N9N9SRSTJ$$& 7$($?$?$A!!--d.F.F.HI!:::F!&&&6	7 7 .\(7 7s   AE//E8c                 &    | j                  |       y)u   
        Оповестить родителя, что ему нужно пересчитать свой агрегат actual_complete
        N)r)  )rP   r   s     r5   !from_child_update_actual_completez.CmfGanttTask.from_child_update_actual_complete  s     	++,ABrR   c                    | j                         syt        j                         5  | j                         }|j                  | j	                                |j                  |        |j                  d       ddd       y# 1 sw Y   yxY w)uP  
        Оповещение родителя.
        Передаем себя, т.к. мы еще можем быть не сохранены и родитель не сможет получить наши данные
        Другой вариант: опочещать через отдельный таск в celery
        NFr  )rW   r-   r{  r   rd   rj  r/   )rP   r   s     r5   r  z1CmfGanttTask.notify_parent_update_actual_complete  s     **,  " 	5 $ ; ; =))$*B*B*DE??E ""e"4	5 		5 	s   ABBc                    | j                   s| j                  r| j                  d      D ch c]  \  }}|	 }}}|h dz
  }|rk| j                  j                  j                          | j                  j                  r1| j                  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                  r2| j                  r&| j                  | j                  k  rt        d	d       | j                  j                  r*| j                  s| j                  d
v rt        dd       y y y y c c}}w )NT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   k_changed_fieldss       r5   check_user_inputzCmfGanttTask.check_user_input  s   {{t.2jjDj.IJFQaJNJ ,.ttN		!!&&(99$$II%%??@RX\XaXa?b&&4+?+? d lpq&&4+?+? Z bfg$$//43M3M3X3X((T-G-G--0I0II|  EI  J$$//''D,E,EIi,i  r $& -j' 0% Ks   F: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| _        y y 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   c                 	   t         j                  d| j                   d|        | j                  j                  dk(  ry | j
                  j                  r| j
                  r| j
                  j                  r<| j                  | j
                  j                  k7  rd}| j
                  j                  }n| j
                  j                  s| j                  r| j
                  j                  j                  | j                                | j
                  j                  j                  | j                  d       | j
                  j                  j                  d       y t        | j                  xs6 | j                  xs( | j                   xs | j"                  xs | j$                        }|s||sz| j                  s| j                  j                  dv sV| j                  s|sH| j                  j                  r| j                  r| j                  | j                  j&                  k7  r_|ry |r?|| _        | j                  | j                  _        | j                  j                  d       ng| j                  j                  sQ| j                  j)                          | j                  j                  | _        | j                  j                  d       |s| j*                  r| j-                         }|D ]k  }|j                  r|j                  | j                  k7  s)|j                  | j                  d|dz   	       |j/                          |j                  d       m |s| j1                         r| j1                         }	|	j                  | j                                |	j                  j                  dk7  rh|	j                  r|	j                  | j                  k7  rC|	j                  | j                  d|dz
  
       |	j/                          |	j                  d       | j
                  sW| j                  j&                  r%| j3                  | j                  j&                         | j5                  | j                         y y y y y )Nz!check_gantt_project: gantt_task: z	, level: rY   T)r   r   r-  )z	task.epicztask.subprojectrc  )r   r  level)r   r   r|  )r  r  rb   r   re   r   r   r   r3   r   rd   rH  r/   boolr   r   r   r   r   r   _calc_gantt_projectr   rs   _calc_outline_numberrW   r  r  )
rP   r  r   r   from_importr|  plan_fields_are_usedrO  rP  r   s
             r5   rH  z CmfGanttTask.check_gantt_project4	  s    	
3DGG9IeWMN99!!%99 &&##11d6H6HDL\L\LjLj6j(,'$($4$4$B$BM))77D<N<N$$22>>t?W?W?YZ$$22FFUYUgUg  }AF  B$$2277$7G#!! %%""   
  !&&499+A+AEe+e&&+?""--$2D2DI[I[_c_q_q_u_uIu%2"*.*<*<		'		.''22		--/%)YY%<%<"		.%$*>*>"<<>"- 8J%33z7O7OSWSeSe7e"66TEWEWmqy~  BC  zC6  D"779"$7	8 (//1$($?$?$A!!--d.F.F.HI$))66:NN,::>O>]>]aeasas>s)==DL^L^sw  @E  HI  @I=  J)>>@)...>##%%));;D<N<N<R<RS2243E3EF $K Jv2D-rR   c                    t         j                  d| j                  j                  j                   d| j                  j
                  j                   d|        |dkD  r<t        d| j                  j                   d| j                  j
                   dd	       |s| j                  j                  }d
d| j                  gddg dgg}t        j                  j                  |g d      D ci c]=  }|j                  j                  |j                  j
                  |j                  xs df? }}d }t        j                  j!                  ddt!        |j#                               gg dgg d      }|D ]  }||j                  j                  j                     \  }	}
d }|j$                  j&                  }|	dk(  r;|j(                  j                  }|
rt        j*                  j-                  |||
      }n|	dk(  rU|j(                  j                  }| j.                  j                  xs d|
z
  }t        j*                  j-                  |||      }n|	dk(  r:|j                  j                  }|
r~t        j*                  j-                  |||
      }n\|	dk(  rU|j                  j                  }| j.                  j                  xs d|
z
  }t        j*                  j-                  |||      }nw|r|s}t        j*                  j1                  |||      s|} n |sc| j2                  rW| j2                  j4                  }|j7                  |j9                                |j:                  s|j=                  ||dz         }|S c c}w )Nz0_get_task_blocking_back_movement start task_id: r  z
), depth: r}   u[   DEV: Защита от рекурсии: _get_task_blocking_back_movement: if depth > 100 "r   rt  Tr   ra   r[   r_   rc   system.finish:startsystem.finish:finishsystem.start:startsystem.start:finish)ri   r,  r_   r\   r   r8  r"   r[   N)z	task.nameztask.idr   r   project.calendar.timezoner  r  r  r  rc  )target_datedepth)r  r  r   r   r   r   r   r   r'   rg   rh   ri   rb   relation_typer,  r   rf   keysr   r   r   r   r   r   r   r   r3   r   rd   r    _get_task_blocking_back_movement)rP   r  r  
_filter_inrp   before_tasks_with_lagsblocking_gantt_taskbefore_gantt_tasksbefore_gantt_taskrel_type_coder,  before_dater   rU  r   s                  r5   r  z-CmfGanttTask._get_task_blocking_back_movement	  s   	B499>>CWCWBXXZ[_[d[d[i[i[o[oZppz  |A  {B  C  	D3;stxt}t}  uC  uC  tD  DG  HL  HQ  HQ  HV  HV  GW  WX  Y  ae  f//55K dii(!4  *F  G

 //55Z  QD5  E"
 LLOOc//44c6G6G6L1MM"
 "
 ##0055d+A+F+F+H&IJLbcq 6 
 "4 	+ABSBXBXB[B[BaBa+b(M=K(0099H 55/AAGG "("4"4"I"I(T_an"oK"88/AAGG //55:mK$00EEhP[]ef"66/@@FF "("4"4"I"I(T_an"oK"77/@@FF //55:mK$00EEhP[]efk !!66xkZ&7#=	@ #t'7'7 $ 0 0 > >))*;*O*O*QR$..&7&X&Xepx}  AB  yB&X  'C#""a"
s   /ANc                 B   | j                   j                  s| j                  j                  rt        j	                  d| j
                  j                  j                   d| j
                  j                  j                   d| d| j                   j                   d| j                   j                   
       | j                   j                  xrE | j                   j                  xr- | j                   j                  | j                   j                  k  }| j                  j                  xrE | j                  j                  xr- | j                  j                  | j                  j                  k  }|s|r9|r7| j                         }|r%t        d|j
                  j                   dd	       d
d| j
                  gddg dgg}t        j                  j                  |      r<t!        t        j                  j"                  d| j
                  j$                  i       y y y )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   ri   r[   r_   rc   r  r   r8  rp  )r   r   r   r  r  r   r   r   r   rJ  r   r  r   r'   rg   r   rx  sort_task_by_order_relationsrb   )rP   	from_savefinish_date_is_chagnedstart_date_is_chagnedblocking_task_filter_outs         r5   rN  z*CmfGanttTask._check_start_finish_relations	  s2   !!,,0E0E0P0PGGCDIINNDXDXCYY[\`\e\e\j\j\p\p[qq  AJ  @K.t/E/E/I/I.JJhimii  jD  jD  iEF G &*%;%;%?%?  &[DDZDZD^D^  &[cgcycyc}c}  AE  AW  AW  A[  A[  d["$($9$9$=$=  %V$BWBWB[B[  %V`d`u`u`y`y  }A  }R  }R  }V  }V  aV!&*?Y $ E E G  bcpcucuczczb{ |b bimo T499-%t  .J  KK '',,K,@%f&>&>&[&[enptpypyp|p|d}~ A# 1QrR   )rw  r  from_sort_orderc                B   |r"| j                           | j                  |i | | j                  |       | j                  j                  r| j                  j                  d       | j                          | j                          | j                          | j                          | j                          | j                          t        |   |i |}| j                  j                  rCt        j                  j!                  | j                  | j                  j#                                | j$                  j                  rCt        j                  j!                  | j                  | j$                  j#                                |s| j'                  d       |S )N)r  Tr-  )r"   r   )r  )rv  r  r  r   r   r/   rO  rH  r,   _alert_task_agile_plan_datesr  rL  rz   r   r'   
CmfCommentadd_comment_audit	html_diffr   rN  )rP   rw  r  r  r  rq  r   r{   s          r5   r/   zCmfGanttTask.save	  sA   !!#D00

':
; 99IINNTN*..0  "!))+!!#glD+F+  ++//tyytG\G\GfGfGh/i!!,,//tyytG]G]GgGgGi/j...>
rR   c                 D    | j                          t        |   |i | y rT   )r   rz   _save_import)rP   r  rq  r{   s      r5   r  zCmfGanttTask._save_import
  s!    !!#d-f-rR   )TEXKOM_db_deletefrom_task_deletec                   | j                  g d       | j                  r| j                  | j                         |r~t        j                  | j                         t        j                  j                  | j                  d      D ]0  }t        j                  |       d |_
        |j                  d       2 n4| j                  r(| j                  j                  | k(  r|st        dd       | j                  rB| j                  j                  | k(  r)| j                  | j                  xs | j                         t        | @  |d|i|S )N)task.op_gantt_taskztask.cmf_deletedr   r   outline_index_numru   T)r3   include_deletedr-  uY   Нельзя удалять Оперативную гант задачу у задачи!r   r  )r   r   outline_remover   r  r  rb   r'   r  rf   r3   r/   r   r   r  rz   r  )rP   r  r  r  rq  r   r{   s         r5   r  zCmfGanttTask.delete
  s    L 	M 0 01 GGDGG++$''SW+X *%)"		D	)* yyTYY44<'y  BF  G9900D833D4D4D4ZHZHZ[w~tQ6FQ&QQrR   c                     | j                  g d       t        |   |i |}| j                  rB| j                  j                  | k(  r)| j                  | j                  xs | j                         |S )N)r  r   r   )r   rz   restorer   r3   r  r   r   )rP   r  rq  r   r{   s       r5   r  zCmfGanttTask.restore
  sa    OPgot-f-9900D8..t/?/?/U4CUCUV
rR   c                     t        |   di | | j                  ry t        j	                  d       t
        j                  j                  | dd       t        j	                  d       y )N_CmfAutomationCrudTrigger startupdatebefore_save_CmfAutomationCrudTrigger end )rz   before_save_hookr  r  r  r'   CmfAutomationCrudTrigger	crud_hookrP   rq  r{   s     r5   r  zCmfGanttTask.before_save_hook(
  sO     *6*;;	12''11$-P	/0rR   c                     t        |   di | | j                  ry t        j	                  d       t
        j                  j                  | dd       t        j	                  d       y )Nr  r  
after_saver  r  )rz   before_save_data_hookr  r  r  r'   r  r  r  s     r5   r  z"CmfGanttTask.before_save_data_hook2
  sO    %//;;	12''11$,O	/0rR   c           	      z   t         j                  r| j                  sy t         j                  t         j                  j                  j
                  dg|| j                  j
                  | j                  d      t         j                  | j                  j
                  d}t        d|d    ||d   |d   g       y )Nproject_notifyTrm  )initiatorSessionTabIdinitiatorCurrentPersonactioninitiatorActioninitiatorObjIdinitiatorObjChangedFieldsu   initiatorСomponentId	projectIdzproject_notify-r  )roomevent_persons)	r  session_tab_idrK   current_personrb   r   r  component_idcmf_emit_event)rP   initiator_actionevents      r5   r  zCmfGanttTask.project_notify<
  s      &'%5%5&'&6&6&9&9&?&?'(/"ggmm)-d)C%&^^..
 	{);(<=u5Q\K]nst  oA  nB  	CrR   c                 r   | j                   s| j                  sy | j                  j                  r<| j                  r0| j                  s$| j                  | _        | j                  d       y | j                  j                  r<| j                  r0| j                  s$| j                  | _        | j                  d       y | j                  j                  r| j                  s"| j                  j                  rB| j                  r5| j                  | _        | j                  | _        | j                  d       y y y )NTr  )	r   r>   r    r   r!   r   r/  r   r\  rU   s    r5   rO  z.CmfGanttTask._pass_actual_dates_to_sched_datesU
  s   t'J'J!!,,1G1GPTPgPg$($:$:D!00T0B""--$2I2IRVRhRh%)%<%<D"11d1C ##..43J3J''22t7M7M$($:$:D!%)%<%<D"11d1C 8N2rR   c                 (   t         j                  j                  |       }|sy |j                  |j	                                |j
                  rt        d       y d}|j                  r|j                  |_        |j                  r|j                  |_
        |j                  j                  r)|j                  j                  s|j                          d}n(|j                  j                  r|j                          d}|r|j                  d       y y )Nrh  u   Нельзя пробрасывать фактические даты в плановые у родительских задачFTr-  )r'   r   r(   r   rd   r   r   r    r   r!   r   r   r/  r\  r/   )r  r2   
needs_saves      r5   r   z3CmfGanttTask.force_pass_actual_dates_to_sched_datesl
  s    ((,,,>
z==?@%%  Y  Z
''*4*F*FJ'((+5+H+HJ(&&11*:V:V:a:a779Z))4488:ZOOdO+ rR   c                    | j                   j                  s| j                  j                  sy d}d}| j                  j                  r1| j                   r%| j                   | j                  j                  k  rd}| j                  j
                  r1| j                  r%| j                  | j                  j
                  kD  rd}g }|s|r| j                  j                  ddg       | j                  j                  D ]d  }|r%|j                  r| j                   |j                  k  s*|s-|j
                  s:| j                  |j
                  kD  sT|j                  |       f |rd| j                  j                   d| j                  j                   dt        |      dk(  rd	nd
 d}|D ]"  }|d|j                   d|j                   dz  }$ t        |j                  d             y y )NFTzlists.plan_start_datezlists.plan_end_dateu   Задача "r   uI   ) выходит за диапазон плановых дат спискrc  u   аu   oв: r  z),,)r   r   r   r   rT  rU  r   listsr9  r   r   r  r   rstrip)rP   alert_start_datealert_end_datealert_lists	task_listra  lsts          r5   r  z)CmfGanttTask._alert_task_agile_plan_dates
  s   %%00D4J4J4U4U 99$$)>)>$$tyy'@'@@#' 99""t'='=%%		(?(??!%~II!!#:<Q"RS!YY__ 2	%)*C*CH]H]`i`y`yHy&9+B+BtG]G]`i`w`wGw&&y12 #DIINN#33tyy~~6F G]ehiteuyzez]a  AF  ]G  GHIC" 4388*Bsxxj334cjjo& rR   c                 F   | j                   j                  dk(  ry ddddd}d }|j                         D ]j  }t        | |      }|j                  s|j
                  rd }d }|dv r^d}|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                         }|j                  }|rF|j                  t                     }|t        j                  |j                  j                        z   }|j
                  j                  t                     }|t        j                  |j                  j                        z   }t        |j                  j                  d	z  d	      \  }}d|dd|d
}|j                  d       d| }|r|j                  d       d| nd}t!        d| j                   j"                   d| j                   j$                   d||    d|xs |j                   d|xs |j
                   d       |j
                  r|j                  s+t!        d| j                   j"                   d| j                   j$                   d||    d       m y )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   re   r  r   r   rJ  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   rM  z'CmfGanttTask._alert_changed_plan_fields
  s   99!!%99 JE H!O	
  ++- &	^JD*-E99$(M$(M!%EE(0 993899?EIIPRNjH/7nC
3?Ov,VM/4yyB		B*+3C.Js;K6(R!%NN''+'9'9';H#(99#'/':':57'CH'/",,xGXGXG^G^2_'_H#(99#7#7#@#+bll8CTCTCZCZ.[#['-h.?.?.E.E.KR'Pf(,T$Kq&E+3+<+<=N+O*PPQR]Q^(_ck8+<+<=N+O*PPQR]Q^(_qy 5diinn5ER		GWWtu{  }G  vH  uI I(5EII6f]=Weii<XXY[ \uyy 5diinn5ER		GW  XF  GM  NX  GY  FZ  Z\  ]  ^M&	^rR   c                    g }| j                   j                  r|j                  d       | j                  j                  r|j                  d       | j                  j                  r|j                  d       |ret
        j                  j                  g ddd| j                  gg      r3t        t
        j                  j                  | j                  |d	       y y y )
Nr   r   r   )r"   rE  Nr8  r[   r   )r8  ru  rp  )r   r   r9  r   r   r'   r   r   r8  rx  calc_variance_job)rP   ru  s     r5   rL  zCmfGanttTask.calc_variance
  s      ++!!"45!!,,!!"56))!!"23f1166?UXacgimiuiuWv>w6x!##55#'<<*8: y>rR   ru  u<   Расчет отклонения задачи от baseline)rd  re  rf  r  c                    d }t         j                  j                  | ddg      }|sy |j                  }|j	                  |j                                t         j                  j                  dd|j                  gdgdg	      D ]?  }t         j                  j                  d
d| gdd|gg|j                               }|s>d|v r1 ||j                  |j                  |j                               |_        d|v r1 ||j                  |j                  |j                               |_        d|v r&|j                  xs d|j                  xs dz
  |_        |j#                  d       |j$                  s|j                  |_        |j                  |_        |j                   |_        |j#                  d       t'                B y )Nc                     | }|}d}|rM|rK||k7  rF||kD  r||}}d}t         j                  j                  ||j                  |j                        }||z  S y)Nrc  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
  sn    G!ED5W%5U?%*GUGD++@@%#MM++ A 
 }$rR   rK   r3   ri  r"   r[   z-active_baselineactive_baseline)r]   order_byr#   r8  r\   r   r   r   r   Tr-  )r'   r  r(   r3   r   rd   CmfGanttBaselinerf   rK   r   r   r   r)   r   r*   r   r+   r/   r  
cmf_commit)r8  ru  r  r   r2   r1   baseline_gantt_tasks          r5   r  zCmfGanttTask.calc_variance_job
  s   
	$ ~~!!WlO5T!U''
z==?@//44XtT__<]?Q>R=N<O 5 Q 	H #)"5"5"9"99dT[B\CKTS[B\B^AKA_A_Aa #: #c '!^35IJ]JnJnJTJeJeJTJbJbJd6f#2 #n46JK^KpKpKUKgKgKUKcKcKe7g#3  >19C9R9R9WVW\o\~\~  ]D  CD  9E#5$$t$4'',?,N,N
)-@-P-P
*/B/T/T
,$/9	rR   c                 J   | j                   j                  s| j                  j                  sy | j                  j                  dk(  rd| _        d| _        d | _        y | j                   j                  rm| j                   sa| j                   j                  rJ| j                  }| j                  j                  r| j                  j                  }| j                  |       y | j                   sd| _        d| _        d | _        y | j                   j                  r3| j                   r'| j                   j                  s| j                          y | j                  j                  rC| j                  s&| j                  | j                  j                         | j                          y y )NrY   r   )remove_from)r   r   r   r   re   outline_numberoutline_parent_strr  r   r  outline_insert_downr  r:  s     r5   r  z!CmfGanttTask._calc_outline_number3  sR   ))**99!!%99"$D&(D#%)D"((1C1C!!%%))##..!--11F###7!!"$D&(D#%)D"((T-?-?HZHZH^H^$$&&&;;##0@0@0D0D#E$$& 'rR   c                    | j                  | j                  j                  | j                  j                         d| _        | j                  r%| j                  j
                  j                  | _        t        j                         5  t        j                  j                  dgg dd| j                  gdd| j                  gg ddd| j                  gg	      j                  }d d d        r|d
z   | _        nd
| _        | j                  r<| j                  rM| j                  xs d d| j                  j                  d| _        n| j                  j                  d| _        | j                  j                   r{t#        t        j                  j$                  | j                  j                  j                  g| j                  j                  g| j                  j                  j                  g       y y # 1 sw Y   xY w)Nr   max__outline_index_numr   r  r   )r"   r  Nrb   rE  )r#   r  r]   rc  r   06r  )_outline_lock_lvlr   rb   r   r  r3   r  r-   r{  r'   r   r(   r  r  r   r   r   rx  _outline_recalc_childrens)rP   	max_indexs     r5   r  z CmfGanttTask.outline_insert_downU  s   t1144d6F6F6I6IJ"$&*&6&6&D&D&S&SD#  " 	%++//01"C)9)9:$c4+=+=>)4)	 0 	 %$ 	% %.]D"%&D"&& *.)@)@)FB(GqI_I_IeIefhHi&j#%)%;%;%A%A"$ED99$$!&"5"5"O"OX\XaXaXdXdXjXjWknrnunun{n{m|  C  Q  Q  T  T  Z  Z  W[  \ %/	% 	%s   AG55G?c           
         | j                  g d       | j                  | j                  j                  | j                  j                         d }|rIt
        j                  j                  |ddg      }|j                  | j                  k7  rt        dd       | j                  j                  }|sd}d| _	        d}d}|}d}nJ|j                  j                  j                  }||k  rd}|dz   | _	        |dz   }|}d}nd	}|| _	        |}|}d
}| j                  r0| j                  xs d d| j                  j                  d| _        n| j                  j                  d| _        d}	t
        j                  j                  j                   j#                         j%                  |	| j                  j                  j                  | j                  j                  j                  | j                  j                  |||d      }
|
D cg c]  }|d   	 }}|
D cg c]  }|d   	 }}| j&                  j(                  r/|j+                  | j&                  j                  j                         |rGt-        t
        j.                  j0                  ||| j                  j                  j                  g       y y c c}w c c}w )N)r   r   r  r  rw   zop_gantt_task.outline_index_numr   ri  u   outline_insert_after можно вызывать только для задач на том же уровне. Сначала измените parent_taskTr   rc  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
        )rn  ro  rb   from_outline_index_numto_outline_index_numir8  rb   r   )r   r  r   rb   r   r'   r  r(   r   r  r   r3   r  r  	CmfPersondp_ddSessionexecuter   r   r9  rx  r   r  )rP   prev_task_id	prev_taskold_outline_index_numprev_outline_index_num	insert_upr  r  r  sqlr   r	child_idschild_gantt_idss                 r5   r   z!CmfGanttTask.outline_insert_aftert  s    	|}t1144d6F6F6I6IJ	**lDegtCu*vI$$(8(88  w  @D  E
 !% 6 6 < <%&"%&D"I%&"#8 A%.%<%<%N%N%T%T"%(== 	)?!)C&)?!)C&'<$!	)?&)>&'=$ %)%<%<%B$C1TE[E[EaEabdDe"fD%)%;%;%A%A"$ED !!%%--/77"..1177 $ 2 2 5 5 ; ;''--&<$8>
  ,//aQy\/	/,/0q1T70099$$TYY\\//0!&"5"5"O"OW`bqsw  tF  tF  tI  tI  tO  tO  WP  Q 	 00s   J6J;c                    | j                   sy d }|r|j                  j                  }| j                  | j                  j                  |       d| _        d| _        t        | j                         }d | _         d}t        j                  j                  j                  j                         j                  ||| j                  j                  j                  || j                  j                  d      }|D cg c]  }|d   	 }}|D cg c]  }|d   	 }}|rFt        t        j                  j                   ||| j                  j                  j                  g       | j"                  r{| j"                  j$                  rdt        j                  j'                  | j"                  j$                  j                  dg      j                  | j"                  j$                  _        y y y c c}w c c}w )	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
        )rn  ro  r  rb   r8  rb   r   r  ri  )r  rb   r   r  r   r  r  r   r'   r  r	  r
  r  r  rx  r   r  r   r3   r   )	rP   r  remove_from_idr  r  r   r  r  r  s	            r5   r  zCmfGanttTask.outline_remove  s   %%(^^11Nt1144nE"$  #D$:$: ;!%
 !!%%--/77, $ 2 2 5 5 ; ;%:''--	>
  ,//aQy\/	/,/0q1T700!&"5"5"O"OW`bqsw  tF  tF  tI  tI  tO  tO  WP  Q 0 0 > >##((D,<,<,J,J,M,MWgVh(ixx **9 !? 00s   7G'	G,c                 :    t         j                  d| d|        y )NOUTLINE_NUMBER_rt  )r-   cache_obj_lock_get)r0   ro  rn  s      r5   r  zCmfGanttTask._outline_lock_lvl  s"     	""_5E4FaGW#XYrR   uY   Вычисление структурных номеров у дочерних задач)r  rf  c                    t         j                  d       t        j                  j                  j                  t        j                  j                  |        t        j                  j                  j                  t        j                  j                  |       g g fdt         j                  d        |        t         j                  d       t        j                  j                  j                  t        j                  j                         t        j                  j                  j                  t        j                  j                         t         j                  d       y )Nz)_outline_recalc_childrens init invalidatec                 
   t         j                  dt        |               | D ]"  }t        j                  j                  |       $ t         j                  d       d}t        j                  j                  j                  j                         j                  |t        |       d      }g }|D ]C  }|d   r|j                  |d          j                  |d          j                  |d          E |r	 	|       y y )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_listro  r   r8  rb   )r  r  r  r'   r   r  r  r	  r
  r  r  tupler9  )
parent_id_list	parent_idr  r   recursive_parent_id_listtfinish_gantt_invalidatefinish_invalidatero  recalc_subtrees
         r5   r%  z>CmfGanttTask._outline_recalc_childrens.<locals>.recalc_subtree  s   GGI#nJ]I^_`+ S	##556F	RS GGHJC ""%%))113;;C',^'<$4B C (*$ 8&',33AiLA!((96'..qw7	8
 (78 (rR   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  rG  r   )idsgantt_task_idsro  r#  r$  r%  s     `@@@r5   r  z&CmfGanttTask._outline_recalc_childrens  s    
 	
;=(()B)BCH(()<)<)G)GX"$	9D 	
@Bs	=?(()B)BDUV(()<)<)G)GI`a	/1rR   uB   Перевычисление структурных номеровc                    | r| g}n?t         j                  j                  ddgg dd      }|D cg c]  }|j                   }}t        j                  dt        |              |D ]m  } t        j                  d|  d       t               }|j                  d        |s;|j                         }t        j                  d|  d	|        d
}t         j                  j                  j                  j                         j                  ||| d      }t               }|D ]/  }|d   r|j                  |d          |j                  |d          1 t                t        j                  d       t         j"                  j$                  j'                  t         j                  j(                  t+        |             t        j                  d       |r3p y c c}w )Nr,  rb   )re   r  rY   T)r#   r]   include_systemu<   _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
                )rn  ro  r   r8  z&_outline_force_recalc cache invalidatez-_outline_force_recalc finish cache invalidate)r'   r  rh   rb   r  r  r  ry  rz  popr  r	  data_driverr  r  r  r&  r'  r(  r)  rG  rf   )	ro  gantt_project_id_listr   r  process_parent_id_setrn  r  clean_cache_idsr"  s	            r5   _outline_force_recalcz"CmfGanttTask._outline_force_recalc  s    %5$6!..&&tTlCn  @D&  EC36$7aQTT$7!$7	NsShOiNjkl 5 D	JGGEFVEWWijk$'E!!%%d+'!6!:!:!<IJZI[[mn|m}~%L &&))55==?GG&4(8N  #&% 6A*+-11!I,?#'')56 @B!!001J1JDQ`LabGIA (	D	J %8s   Gc                 R    t        t        j                  j                  d| i       y )NrK   rp  )rx  r'   r   calc_critical_path_job)rK   s    r5   r   zCmfGanttTask.calc_critical_pathl  s    f11HHR^`jQklrR   rK   u.   Расчет критического пути)rd  re  rf  r  r  c           
      r  	
 fd
fdfd	d	
f	d	t         j                  j                  | dg      }|st        d|  dd	
       |j                  j
                  }|j                  |j                                |j                  d	d	       t         j                  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}t         j"                  j%                  |      D ci c]  }|j&                  j                  | c}t        j)                               D ]
  } |        y c c}w )Nc                 h    | vr)t         j                  j                  dd| g      }|| <   |    S )Nrb   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  sE     $55#0044T4<W`f4g
3=!-0$]33rR   c                 0   | j                   vrydd| j                   gg dg dg}dg}t        j                  j                  ||      }|st	        d| j                    d	       |j
                  j                  | j                   <   | j                      S )
NrK   r[   )rv   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*
 //#)#6#6#:#:'RY#:#Z ' w  yC  yN  yN  xO  P  X\  ];K;];];c;c!*"7"78$Z%:%:;;rR   c                     | j                   vrZ| j                  ddg       | j                  j                  xs" t        j
                  j                  ddg      | j                   <   | j                      S )Nzproject.calendarr  rA  r   rB  )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&&(:<W'XYAKASASA\A\  Bc`f`r`r`v`v  }M  Wa  Vb`v  ac'
(=(=>*:+@+@AArR   c                   	  |       }|j                   j                  v ry |r||j                   j                  <   nZj                  |j                   j                  d       }|s2|j                  r&j                  |j                  j                  d       }d |_        d |_        d |j                  _        d|_        |j                  r|j                  r|j                  sk|j
                  j                  sB|j                  j                  s,|j                  j                  s|j                  j                  r|j                  d       y |sd}t        j                  d| d|j                           |j                  rB|s@|j                  j                  vr(  |j                  j                        |dz          y |j                   j                  v rEt#        dt$        j                   j&                   d	t$        j                   j(                   d
d       n%j+                  |j                   j                         |}|j                   j                  v rg }|r|j-                  |       |j                   j                     D ]q  \  }}  |      |dz          |v s|   j
                  }	|r2t.        j0                  j3                   |      |	t5        |             }	|j-                  |	       s |rt7        |      }|j                   j8                  s||_        t.        j0                  j3                   |      |j                  j                  t5        |j                               |_        t.        j0                  j;                   |      |j                  j                  |j                  j                        |_        |j                  j                  dk(  |_        |j                  d       |r||j                   j                  <   |j                   j8                  r|j                   j=                  dg       |j                   j>                  D 
cg c]  }
|
j                  j                   }}
d }d }d }d}|D ]  }  |      |d|dz          j                  |d       }|s-|r"|j
                  rt7        ||j
                        n|j
                  }|r"|j                  rtA        ||j                        n|j                  }|r"|j                  rt7        ||j                        n|j                  }|r|j                  sd} ||_        |jB                  r|xs  |      |_        t.        j0                  j;                   |      |j                  j                  |j                  j                        |_        |j                  j                  dk(  |_        n||_        ||_        ||_        |j                  d       |j
                  j                  |j                  j                  |rt7         |      |      |_        n |      |_        t.        j0                  j3                   |      |j                  j                  t5        |j                               |_        t.        j0                  j;                   |      |j                  j                  |j                  j                        |_        |j                  j                  dk(  |_        |j                  d        |j
                  j                  |j                  j                  |j                  j                  |j                  j                        |j                   j                  <   y c c}
w )NFTr-  rc  zcalc_critical_path: level: z, )r|  uQ   calc_critical_path: Обнаружен цикл в связях в задаче "r   rt  r   )r   r   rU  r  r   zchild_tasks.op_gantt_task)late_start_datefrom_parent_taskr|  rB  late_finish_daterz  is_critical_path)"rb   r   r(   r   rj   rB  rE  rz  rF  r   r   r   r   r/   r  r  r   r   rP   r   r   rz  r9  r'   r   r   r   r   r   r   r   rO  r   r   )r  rB  rC  r|  r2   #following_tasks_min_late_start_datefollowing_late_start_datesfollowing_gantt_task_idr,  following_late_start_dater"  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   r9  r>  done_gantt_tasksgiven_late_start_date_by_gt_idtask_out_linksvisited_gantt_taskss                     r5   rS  z>CmfGanttTask.calc_critical_path_job.<locals>._calc_is_critical  s2   (7J}}""&66FU.z}}/B/BC #A"D"DZ]]EXEXZ^"_&:+A+A&D&H&HI_I_IpIprv&wO)-J&*.J'+/J""(*/J'//J4P4PU_UnUn..99!22==!--88!22==OOdO3GG1%:??:KLM &&(**;;CVV!/*2H2H2Y2Y"Zbgjkbkl}}""&99mnrnwnwn|n|m}  ~A  BF  BK  BK  BP  BP  AQ  QR  S  [_  `#''
(;(;<2A/}}""n4-/*".55oF>LZ]]M`M`>a U:+]%o6M&NV[^_V_`.2BB4DE\4]4m4m1(8>8J8J8_8_)6z)B(A*-m*<)< 9` 95
 399:STU .:=>X:Y7%??::6Y
35;5G5G5\5\%2:%>$.$?$?$E$E&)**C*C&D%D 6] 6
2
 281C1C1X1X%2:%>$.$@$@$F$F","="="C"C 2Y 2
.
 7A6L6L6R6RVW6W
3"$72Fi.z}}/B/BC..++-H,IJMW__MhMh*i1+=+=+C+C*i'*i,0)-1*(,%*/'+B 7'%o6I&J6Y7;,1AI7 '7&:&:;NPT&UO*  59X9X 144MOnOn0o^m^}^} . 6/:Z:Z 255OQ`QqQq1r`o  aA  aA / 1_5P5P -00EGbGb,cVeVqVq *27W7W26/!7$ .G
*''2U2}Yqr|Y}J/-3-?-?-T-T!.z!: * < < B B(99?? .U .J*
 3=2H2H2N2NRS2SJ/2LJ/-BJ*2IJ/$/**008J<W<W<]<]<e"256Nz6Z\k2lJ/2J:2VJ/-3-?-?-T-T*:6&77==!*";";<< .U .
*
 *0););)P)P*:6&88>>$55;; *Q *
&
 /9.D.D.J.Ja.O
+$/4F * : : @ @!+!<!<!B!B&2288!+!<!<!B!B	5Z]]001y +js   /_
 main_gantt_project.op_gantt_taskri  u   Проект с id "u   " не найден.Tr   )rj  rk  rR  rD  )	r   r   r   r   rw   ru   r   rB  rE  r   r[   )rv   rE  rY   r  r\   )NFN)r'   rF  r(   r   main_gantt_projectr3   r   rd   rl  rg   get_start_finish_graphsry  r   dictr   r   rK   r   rf   rb   r  )rK   r   gantt_project_gantt_taskrt  r   r2   r  rR  rS  r   r9  r>  r@  rT  r#   r8  rU  r=  rV  rW  s          @@@@@@@@@@@@@r5   r5  z#CmfGanttTask.calc_critical_path_jobp  s   
	4	<	B]	 ]	~ ##'':?a>b'c,ZL8LMUYZ#*#=#=#K#K  ,,-E-Y-Y-[\ @@$bf@g"44LLN!e'(<  ?I  J FG_GqGqGwGw2==CCD"&&)-&c 6AAB="

 PVObObOgOgov  @FOg  PG  HZ]]00*<  H !2!7!7!9: 	-Mm,	- Hs   ,F4u*   Пересчет гант проектовc                 ~   g }| rdd| g}t         j                  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                  j                  ||dz   g||dg      }|sn|D ]  }|j                  xj
                  |j
                  j                  xs dz  c_        |j                  xj                  |j                  j                  xs dz  c_        |j                  xj                  |j                  j                  xs dz  c_        |j                  xj                  |j                  j                  xs dz  c_         |dz  }|j                  j                  |j                  _        |j                  j                  |j                  _        |j                  j                  d       t                 y )Nr   r[   rX  )r#   r]   r   rE  rY   )rx   r[   Nrr  )r  rE  N)r  rE  r   )r   rE  N)r   rE  r   )r  rE  N)r  rE  r   )r   rE  N)r   rE  r   )r  r   r  r   T  cmf_created_at)slicer]   r#   r  r-  )r'   rF  rf   rY  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  sM    "D,7N((--6X5Ybp-q B	G#66M  78M''378M''467M''378M''4 g.%t];030
 3/
 40
 3/	F0F A$1166a4[>D>DAQ@R 7 T #"- aJ!//;;z?U?U?[?[?`_``;!//<<
@U@U@[@[@`_``<!//;;z?U?U?[?[?`_``;!//<<
@U@U@[@[@`_``<a T	! $ 6C5P5P5]5]M''25B5P5P5]5]M''2'',,t,<LEB	rR   c                   	
 	
fd}t        t              
g d| g	g d |       }g d}dg}t        t        j                  j                  |d|      D ch c]5  }|j                  r'|j                  j                  d      r|j                  7 c}      }d	d
|g	 |       }|j                  |       |rdd
|g	 |       }|r
S c c}w )Nc                  $   t               } d}d}	 t        j                  j                  |||z   gd      }|s	 | S |D ]  }|j                  s?|j
                  r3|j                  j                     j                  |j                         N|j                  s[|j                  j                  rr| j                  |j                  j                         |j                  j                     j                  |j                          ||z  })Nr^  r   T)r]   r#   r`  include_archived)ry  r'   r  rh   rn  ro  r   rj   rz  r   cmf_deleted)
parent_idslimitsteptasksr   r;  r   trees        r5   update_treez0CmfGanttTask.get_gantt_tree.<locals>.update_tree  s   JED,,"".%)	 -    " [D..43H3HT//@@AEEdF[F[\,,T5E5E5Q5Q"t'7'7'H'HIT-->>?CCDDYDYZ[ % rR   )r   r[   F)zparent_task.op_gantt_task_idzgantt_project.op_gantt_task_idrj   zparent_task.cmf_deleted)r  r[   factr   T)r]   rf  r#   r  rb   rc   rj   )	r   ry  rf   r'   r   rh   r   
startswithr  )leaf_filterrm  parent_ids_set
tth_filter
tth_fieldsr  task_ids_from_tth_factparent_ids_set_from_tthr;  r   rl  s           @@@r5   get_gantt_treezCmfGanttTask.get_gantt_tree  s    	6 33[A D$3
!]
!%*0*F*F*L*LT^qu  I*L  +J'a*---CMM<T<TU^<_ (+}} 'a "b 56"--56)4@G(]N  'as   :Cc                  ~	   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                  j                  |       t	        d       t        j                  j
                  }t        j                  j
                  }t        j                  j                  j                  j                         }t        j                               }j                         D ch c]  }|D ]  }|  }}}||z
  }t        ||z        }	|j                  |j                   t#        j$                  |j&                              j)                  ||j*                  |j,                  k(        j/                  t1        |j                   j3                  |	      |j4                  dk(  |j6                  dk(              j9                  |j                         j;                         }
|
D ci c]  \  }}||xs d }}}d}t=        dt?        |	      |      D ]@  }|	|||z    }g d}t        j                  jA                  dd|g|d      }|D ]  }|j                   |j                      d<   |jB                  xs d|j                      d <   |jD                  xs tG        d!      |j                      d"<   |jI                  |j                   d      |j                      d#<   |jJ                  xs tG        d!      |j                      d$<   |jL                  xs d|j                      d%<   |jN                  xs tG        d!      |j                      d&<   	 C d}|D ]A  } |       |d'z  }|d(z  dk(  s|t?        |      k(  s't        d)| d*t?        |       d+       C r|jQ                  |jR                  jU                         jW                  |j                   tY        d      k(        j                  tY        d       tY        d"      tY        d%      tY        d&      tY        d,      tY        d-      .      t        j                                      t[                t\        j_                          t        d/       y1t        d0       y1c c}}w c c}}w )2u   
        Пересчитывает 'actual_work', 'actual_cost', 'sched_work', 'sched_cost' от детей к родителям
        c                    | |    d<   | vr|    d   |    d<   |    S d|    d<   d|    d<   d|    d<   d|    d<   |    }|D ]V  } |      }|    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<   X |    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_datarl  s       r5   r}  z6CmfGanttTask.recalc_gantt_tree.<locals>.calculate_node  s   29Ig/ d"4=g4FG[4\	'"=1 ))12Ig~.12Ig~.01Ig}-01Ig}- G}H$ O+H5
'">2j6NN2'">2j6NN2'"=1Z5NN1'"=1Z5NN1O g}-71CDX1YY-g}-71CDX1YY-/29W3En3UW`ahWijvWw/xIg|,/29W3En3UW`ahWijvWw/xIg|,W%%rR   rr  )op_gantt_task.actual_workrE  N)r  rE  r   )op_gantt_task.sched_workrE  N)r  rE  r   )op_gantt_task.actual_costrE  N)r  rE  r   )op_gantt_task.sched_costrE  N)r  rE  r   )%parent_task.op_gantt_task.actual_workrE  N)r  rE  r   )$parent_task.op_gantt_task.sched_workrE  N)r  rE  r   )%parent_task.op_gantt_task.actual_costrE  N)r  rE  r   )$parent_task.op_gantt_task.sched_costrE  N)r  rE  r   u(   Получаем дерево задач)rp  c                      dddddddS )Nr   )r  r   r  r   r  r  r  r  rR   r5   <lambda>z0CmfGanttTask.recalc_gantt_tree.<locals>.<lambda>  s"    [\lm  @A  ST  )U rR   rn  Fr   r^  )r,  r  r  r   r   r  r  rb   rc   T)r]   r#   r  r  r  0r  r  r  r   r   rc  
   u   Обработано u    из u    ветокr  r  )r  r  r   r   r  r  u:   Обновленные данные внесены в БДu/   Нет данных для обновленияN)0printr'   r   rv  r   dp_modelr   r  r	  r/  r  ry  r  r1  rf   queryrb   r
   r0  r  joinr8  r   r]   r   in_r  rg  group_byallranger  rh   r  r  r   r(   r  r   r   r  	__table__r  wherer	   r  r(  flushdb)rp  	GanttTaskTimeTrackerHistorysessionparent_nodesrz  childchild_nodes
root_nodes	all_nodestth_rowstidstth_sum
batch_sizer  	batch_idsr#   r  r2   progress_countrootr}  r~  rl  s                         @@@r5   recalc_gantt_treezCmfGanttTask.recalc_gantt_tree  s    	&D =:
 =9
 >:
 =9$ IF
 IE
 JF
 IE'%
L 	89""11k1J  !U  V	''00	#99BB..##//779499;'-1[[]QQuuQuQQ!K/
|34	 U9<<*<*G*G!HIT$i&7&7;M;W;W&WXVLL$$Y/&33v=&22e; Xill#SU 	 088VS!3a<88
q#i.*5 	_A!!A
N3IF --33D$	;R[asw3xK) _
<FMM	*--(9:D:P:P:UTU	*--(7:D:P:P:`T[\_T`	*--(7AHZ]]\]A^	*--()=>AKA^A^Anbijmbn	*--()=>9C9N9N9SRS	*--(69C9N9N9^RYZ]R^	*--(6_	_  	bD4 aN"a'>S_+L-n-=VC
OCTT_`a		b OO##**,y||y'AAB )- 8 )- 8(6(6!*>!:!*>!:   Y%%'( LNOCDA R( 9s   R3R9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   rs   rd   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r)  r6  r?  r   rK  r/  r\  r^  rb  staticmethodcmf_deferred_jobrn  rl  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  rY  r;  r=  r@  rC  rJ  r  rR  rW  rY  r[  r]  r_  ra  r  r  r  r  rj  r  rv  r,   rH  r  rN  r/   r  r  r  r  r  r  rO  r   r  rM  rL  r  r  r  r   r  r  r  r3  r   r5  rc  rv  r  __classcell__)r{   s   @r5   r   r      s   I**  .F  FK .  @6 -
4 46dW\ !B48 I I      6  *(T+\)9V]9~,bB% 4!,'FV(@*B7H]"~":R6?p>2>$7n i[1M" N " [#zJ8S.L2E"N ejY^:?B?H#!\F90 K* _dV[;7zI.))(;8-.#/J/&?C*`6D "w  NR $o5FQRT3sT 3sj;$zdEL7""6"& %)VK0"

&"'
'
I47(C"&4!:LG\=#~, &*uV[ (T. .3U R211C2. , ,:'B2^h  iAQ5R .ln7n 7B 'D\>EQN$yL Z Z
 "}  IJ  K12 K 12f "fqrsKJ t KJ\ m m l^a*.<lnY-n Y-v "NYZ[G \ GR 1 1f VE VE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   r  rR   r5   <module>r     s6      7 7 / , ,    <V9E< V9ErR   