U
    {yd7                     @   sT   d dl T d dlmZmZ d dlmZ d dlZd dlT d dlm	Z	 G dd de	Z	dS )    )*)ROUND_UP
ROUND_DOWN)	timedeltaN)CmfGanttTaskc                       s  e Zd Zedd Z fddZedd Zedd Zed	d
 Z	edd Z
dd Zdd Zdd Zdd Zdd Zdd ZdcddZdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zddd+d,Zded-d.Zd/d0 Zd1d2 Zdfd3d4Zd5d6 Zdgd7d8Zd9d: Z d;d< Z!d=d> Z"d?d@ Z#dAdB Z$dCdD Z%dEdF Z&dGdH Z'dhdIdJZ(dKdL Z)dMdN Z*dOdP Z+dQdR Z,dSdT Z-dUdV Z.didWdXZ/dYdZ Z0d[d\ Z1d]d^ Z2d_d` fdadb
Z3  Z4S )jr   c              	   C   sj   t  }|jr$|jjjdkr$|j|_|r6||_|j|_||_|j|_t	
  |jddd W 5 Q R X |S )NZ
CmfProjectF)emitnotify)modelsr   parentvalue
class_nameZprojectZgantt_projecttaskparent_taskcmfutilZdisable_notifysave)clsr   baseline
gantt_task r   (./modules/gantt/models/cmf_gantt_task.pycreate_gantt_task
   s    
zCmfGanttTask.create_gantt_taskc                    s    dddddddg}t   | S )Nr   r   task.logic_prefixztask.parent_task.logic_prefixztask.has_child_tasksztask.plan_start_dateztask.plan_end_date)supersave_preload_fields)selffields	__class__r   r   r      s    	z CmfGanttTask.save_preload_fieldsc                 C   s2   | j jrd S | j | j d }t|jtdtdS )Nd   z1.11Zrounding)
sched_costis_null_perform_completeDecimalquantizer   r   resr   r   r   _perform_cost'   s    zCmfGanttTask._perform_costc                 C   s:   | j jrd S | j | j d }t|jtdtd}t|S Nr   1r   )sched_durationr!   r"   r#   r$   r   intr%   r   r   r   _perform_duration.   s
    zCmfGanttTask._perform_durationc                 C   s:   | j jrd S | j | j d }t|jtdtd}t|S r(   )
sched_workr!   r"   r#   r$   r   r+   r%   r   r   r   _perform_work6   s
    zCmfGanttTask._perform_workc                 C   s   | j js| jjrdS ttj| j   }| j ttjkr@dS | j| j   }t|dkrj|| d }nd}|dkrzd}t	|j
t	dtd}t|S )Nr   r   r)   r   )sched_start_dater!   sched_finish_datedatetimenowtimezoneZutctotal_secondsr+   r#   r$   r   )r   Zdelta_now_time_secZdelta_finish_time_secZperform_completer&   r   r   r   r"   >   s    zCmfGanttTask._perform_completec                 C   s   d\}}}| j jrH| j jdkrH| j jj }||   | \}}}|}| jdkrx| j	}|rp|rpt
||}n|pv|}|}| jdkr| j}|r|rt||}n|p|}d }| jr| j}n|}|||fS )NNNNtask.gantt_project0-const3-afterr8   2-before)r   r   logic_prefixop_gantt_taskloadload_fieldsr   get_parent_plan_limitconstrain_start_typeconstrain_start_datemaxconstrain_finish_typeconstrain_finish_dateminconst_durationr*   )r   Zparent_start_limitZparent_finish_limitZparent_duration_limitparent_gantt_taskstart_limitfinish_limitduration_limitr   r   r   r@   W   s,    


z"CmfGanttTask.get_parent_plan_limitc                 C   s  d  } }}| j jsdS tjjdd| j g|  dD ]}|jdkr`|sN|j}n|jr`t||j}|j	dkr|sv|j
}n|j
rt||j
}|jr|s|j}n|jrt||j}|j jr4| \}}}|s|}n|rt||}|s|}n|rt||}|s|}q4|r4t||}q4|||fS )Nr5   task.parent_task=filterr   r8   4-beforer8   1-after)r   has_child_tasksr	   r   listr   rA   rB   rF   rD   rE   rC   rG   rK   get_childrens_plan_limit)r   rI   rJ   rK   r   Zch_start_limitZch_finish_limitZch_duration_limitr   r   r   rV   {   sH    




z%CmfGanttTask.get_childrens_plan_limitc                 C   sB   t | ddrd S d| _|  \| _| _| _|  \| _| _| _	d S )N_calc_plan_limits_cache_doneFT)
getattrrW   r@   _plan_start_limit_min_plan_finish_limit_max_plan_duration_limit_maxrV   _plan_start_limit_max_plan_finish_limit_min_plan_duration_limit_minr   r   r   r   _calc_plan_limits_cache   s    z$CmfGanttTask._calc_plan_limits_cachec                 C   s0  | j r| jsd S | j| j  }| d d d }tt|d d}|d d }| jdkr| jdkr| jr|| j	r|t
ddd	 || _d S | jd
kr| jdkr| jr| j|k r| jr| j	rt
ddd	 t
d || _d S | jdkr,| jdkr,| jr| j|kr,| jr| j	rt
ddd	 t
d || _d S d S )N<      着&?      r8   u   Несовместимые ограничения Плановых Дат и фиксированной ДлительностиTabortrP   rR   u   Увеличили длительность, т.к. Плановые Даты ограничивают её минимальный размерr7   r:   u   Уменьшили длительность, т.к. Плановые Даты ограничивают её максимальный размер)rB   rE   r4   rC   mathceilrA   rD   r*   rG   	cmf_alert)r   delta
delta_days	work_daysr*   r   r   r   _calc_sched_duration   s2    z!CmfGanttTask._calc_sched_durationc                 C   sj   | j rP| jrP| j| j  }| d d d }tt|d d}|d d | _n| j jrf| jjrfd| _d S )Nra   rb   rc   rd   re   r   )actual_start_dateactual_finish_dater4   rC   rh   ri   actual_durationold)r   rk   rl   rm   r   r   r   _calc_actual_duration   s    z"CmfGanttTask._calc_actual_durationc                 C   s   | j jrd S | jjr | jjr d S | j d d }t|d }| jr| jdkr| jt|d | _|dkr| jjj	ddt
  jd	}| j|kr|tdd7 }|| _d S | jr| jdkr| jt|d | _d S | jdkr| jdkr| jrtd
 d S )Nre   ra   rc   r8   )Zdaysrd      r   )ZhourZminutetzinfou   Плановый период может не соответствовать плановой длительности, т.к. все переменные зафиксированы)r*   r!   r/   r0   rh   ri   rD   r   r   replacer1   r2   Z
astimezoneru   rA   rG   rj   )r   rm   Zcalendar_daysZ
today_dater   r   r   _calc_sched_period   s*    
zCmfGanttTask._calc_sched_periodNc           
      C   s  | j jsdS | jdkrdS | jdkrtjjdd| j gdgd}|sFdS t|}d}|D ]6}|r||j|jkr|||jj	pvd7 }qV||jj	pd7 }qV|| }n | jd	krztj
jd
d| j gddgd}|sdS d}d}	|D ]}|r:|j|j jkr:|j ddg ||j jj	pd7 }|j jjdkrj|	|j jj	p4d7 }	q||jj	pHd7 }|jjdkr|	|jj	pfd7 }	q|	| d }n | jdkrdS | jdkrdS | j|k r|| _dS )uB   
        updated_ch_gantt_task - указан, когда
        N0-work
1-completerL   rM   actual_completerN   r   2-story_pointsr   agile_story_pointszstatus.status_typeCLOSEDr   3-costz4-fixed)r   rT   actual_complete_typer	   r   rU   lenidrz   r   ZCmfTaskr?   r|   statusstatus_type)
r   updated_ch_gantt_taskZch_gantt_task_listZtotal_countZsum_actual_completecZres_actual_completeZch_task_listZtotal_story_pointsZfinished_story_pointsr   r   r   _calc_summarry_actual_complete  sR    

z+CmfGanttTask._calc_summarry_actual_completec                 C   s  |    |   | jdkr*| j| _d| _n| jdkrZ| j| _| jr| jrt| j| j| _np| jdkr| j| _| jr| jrt	| j| j| _n@| j| _| jr| jrt| j| j| _| jr| jrt	| j| j| _| jr| jr| j| jkrt
ddd | jr| jr| j| jk rt
ddd | jjr| jr:| jj| jk r| jrR| jj| jkr| jsf| jj| _n\| jdkrtnN| jdkr| jj| jk r| jj| _n&| jd	kr| jj| jkr| jj| _|   | jd
d d S )Nr8   Tr9   rQ   u~   Нельзя указать Дату начала больше зафиксированной у дочерней задачиrf   u   Нельзя указать Дату начала меньше зафиксированной у родительской задачи)1-earlyrQ   )z2-latterr9   rB   
date_field)rn   r`   rA   rB   r/   lock_sched_start_daterY   rC   r\   rF   rj   r   Zplan_start_daterw   _change_parent_start_dater_   r   r   r   #_do_constrain_start_date_is_changedQ  sV    




z0CmfGanttTask._do_constrain_start_date_is_changedc           
      C   s   g }| j  }ddddddg}| jjr`| jjdkr`dd	|gd
d	| jgdddgg}tjj||d}dd	| jgdd	dgg}tj	j|dgd}tt
dd |}dd	|gd
d|gg}tjj||d}	||	 S )NrB   rE   rA   rD   r/   r0   r6   r
   rM   Ztask_idr   z!=rN   Zout_linkzrelation_type.codezsystem.additional_parentin_linkc                 S   s
   | j jjS N)r   r   r   )Zrelr   r   r   <lambda>      z6CmfGanttTask._get_parent_gantt_tasks.<locals>.<lambda>IN)r
   r>   r   r   r<   Zparent_task_idr	   r   rU   ZCmfRelationOptionmap)
r   Znormal_parentsr   r   rO   Zadditional_filterZadditional_parents_relationsZadditional_parents_tasks_idsZadditional_parents_filterZadditional_parentsr   r   r   _get_parent_gantt_tasks  s,    
 

z$CmfGanttTask._get_parent_gantt_tasksc                 C   sd   | j r0| jr0| jdkr0| jj| j k r0tddd | j r`| jr`| jdkr`| jj| j kr`tddd d S )Nr9   ua   Ошибка: Плановая дата начала меньше даты ограниченияTrf   rQ   ua   Ошибка: Плановая дата начала больше даты ограничения)rB   rA   r/   newrj   r_   r   r   r   _do_sched_start_date_is_changed  s    z,CmfGanttTask._do_sched_start_date_is_changedc                 C   sX   | j r*| jdkr*| jj| j k r*tddd | j rT| jdkrT| jj| j krTtddd d S )NrS   ug   Ошибка: Плановая дата окончания меньше даты ограниченияTrf   r;   ug   Ошибка: Плановая дата окончания больше даты ограничения)rE   rD   r0   r   rj   r_   r   r   r    _do_sched_finish_date_is_changed  s    z-CmfGanttTask._do_sched_finish_date_is_changedc                 C   s   |   }|D ]}|jdkr$td q| | r|| rD| | || k r|jdkrt|| rt| | || krttd  d S |jdkr|| r| | || k rtd  d S | | ||< |  |j|d qd S )Nr8   ^   Дата родительской задачи является зафиксированнойrQ   u   Предупреждение: Плановая дата начала дочерней задачи больше плановой даты начала родительской задачиr9   u   Предупреждение: Плановая дата начала дочерней задачи меньше плановой даты начала родительской задачиr   )r   rA   rj   r   r   r   r   parentsrH   r   r   r   r     s&    
 z&CmfGanttTask._change_parent_start_datec                 C   s   |   }|D ]}|jdkr$td q| | r|| rD| | || kr|jdkrt|| rt| | || k rttd  d S |jdkr|| r| | || krtd  d S | | ||< |  || q| jdk| _d S )Nr8   r   rS   u   Предупреждение: Плановая дата окончания дочерней задачи меньше плановой даты окончания родительской задачиr;   u   Предупреждение: Плановая дата окончания дочерней задачи больше плановой даты окончания родительской задачи)r   rD   rj   r   _change_parent_finish_daterA   r   r   r   r   r   r     s(    
 z'CmfGanttTask._change_parent_finish_datec                 C   s  |    |   | jdkr*| j| _d| _n| jdkrZ| j| _| jr| jrt| j| j| _np| jdkr| j| _| jr| jrt	| j| j| _n@| j| _| jr| jrt| j| j| _| jr| jrt	| j| j| _| jr| jr| j| jkrt
ddd | jr| j| jk rt
ddd | jjr| jr4| jj| jk r| jrL| jj| jkr| js`| jj| _n\| jdkrnnN| jdkr| jj| jkr| jj| _n&| jdkr| jj| jk r| jj| _|   | jdd	 | jdk| _d S )
Nr8   TrS   r;   u   Нельзя указать Дату окончания больше зафиксированной у родительской задачиrf   u   Нельзя указать Дату окончания меньше зафиксированной у дочерней задачиrE   r   )rn   r`   rD   rE   r0   lock_sched_finish_dater]   rC   rZ   rF   rj   r   Zplan_end_daterw   r   r_   r   r   r   $_do_constrain_finish_date_is_changed  sZ    




z1CmfGanttTask._do_constrain_finish_date_is_changedFc                 C   s   | j dkr | jdkr tddd |   | jrF| j| jkrFtddd | jrd| j| jk rdtddd |   |s| jr| js| j| _	| j
dd n| j| j	k rtddd | jd	d
 d S )Nr8   u   Нельзя менять длительность, если зафиксирована дата начала и дата окончанияTrf   u   Нельзя указать Длительность больше зафиксированной у родительской задачиu   Нельзя указать Длительность меньше зафиксированной у дочерней задачи)from_sched_duration_changedu   Нельзя указать Длительность меньше чем Трудозатраты, когда установлена опция Фиксированные Ресурсы и Трудозатраты зафиксированыr0   r   )rA   rD   rj   r`   r[   r*   r^   rw   
const_workr-   _do_sched_work_is_changedr   )r   from_sched_work_changedr   r   r   _do_sched_duration_is_changed  s"    
z*CmfGanttTask._do_sched_duration_is_changedc              	   C   s(  | j jrd S | j dk r"tddd | jjs2| j | _| jdkr| jjr| jdkrt	
| j | j d }t|d}| jjs|| jkr|| _|   | j jpd| j jpd }| jjr| jjdkrt 8 | jjj }||   || |jdd	 W 5 Q R X |s$| jjr$tj| j| d S )
Nr   uo   "Фактические трудозатраты" стал ниже нуля, выставляем в ноль.Trf   rx   r   r6   F
user_input)actual_workr!   rj   r   rT   actual_myself_workr   r-   is_not_nullrh   floorrF   rz   $notify_parent_update_actual_completer   rr   r   r<   r   disable_aclr=   r>   r?   r   from_child_add_workr   
is_changedr	   ZCmfTimeTrackerZ"_op_gantt_actual_work_changed_hook)r   from_timetrackertmp_complete
work_deltarH   r   r   r   _do_actual_work_is_changed%  s,    




z'CmfGanttTask._do_actual_work_is_changedc              	   C   s   | j jrd S | j dk r"tddd | jdkr~| jjr~| jdkr~t| j | j d }t|d}| j	jsp|| j	kr~|| _	| 
  | jjr| jjdkr| j jpd| j jpd }t 8 | jjj }||   || |jdd	 W 5 Q R X d S )
Nr   ue   "Фактические Затраты" стал ниже нуля, выставляем в ноль.Trf   r~   r   r6   Fr   )actual_costr!   rj   r   r    r   rh   r   rF   rz   r   r   r   r<   r   rr   r   r   r=   r>   r?   r   from_child_add_costr   )r   r   
cost_deltarH   r   r   r   _do_actual_cost_is_changedF  s$    




z'CmfGanttTask._do_actual_cost_is_changedc                 C   s,   | j jrd S | jdkrd S | jdkr(d S d S )Nrx   r~   )rz   r!   r   r_   r   r   r   _do_actual_complete_is_changed^  s    

z+CmfGanttTask._do_actual_complete_is_changedc                 C   sH   | j jp
d| j jpd }| jjs*| j | _n|  j|7  _| j|d d S )Nr   r   )r   r   rr   r   rT   r   r   )r   r   r   r   r   r   !_do_actual_myself_work_is_changedn  s
    
z.CmfGanttTask._do_actual_myself_work_is_changedc                 C   sD   | j jp
d| j jpd }| jjs*| j | _n|  j|7  _|   d S Nr   )actual_myself_costr   rr   r   rT   r   r   r   r   r   r   r   !_do_actual_myself_cost_is_changedx  s
    
z.CmfGanttTask._do_actual_myself_cost_is_changedc              	   C   s  | j jrd S | jjrb| j | jk r| jrFtd| j  d| j ddd q| j| _ td| j d nB|s| j r| js| j | _| j	dd | j
r| j| j k rtd	dd | jjr| jjd
kr| j jpd| j jpd }t 8 | jjj }||   || |jdd W 5 Q R X d S )Nu   Нельзя запланировать меньше Трудозатрат, чем запланировано в подзадачах ( < u`   ). Увеличте Трудозатраты или уменьшите их у подзадач.Trf   u   Указано Трудозатрат меньше, чем запланировано в подзадачах. Выставили uo   . Если нужно уменьшить Трудозатраты, уменьшите их у подзадач.)r   u   Нельзя указать Трудозатраты больше чем Длительность, когда установлена опция Фиксированные Ресурсы и Длительность зафиксированаr6   r   Fr   )r-   r!   r   rT   agregat_workr   rj   rG   r*   r   const_resourcer   r<   r   rr   r   r   r=   r>   r?   r   from_child_agregate_workr   )r   r   r   rH   r   r   r   r     s2    


z&CmfGanttTask._do_sched_work_is_changedc              	   C   s   | j jrd S | j | jk rX| jr>td| j  d| j ddd n| j| _ td| j d | jjr| jjdkr| j jpvd	| j j	pd	 }t
 8 | jjj }||   || |jd
d W 5 Q R X d S )Nu   Нельзя запланировать меньше Расходов, чем запланировано в подзадачах (r   uX   ). Увеличте Расходов или уменьшите их у подзадач.Trf   u|   Указано Расходов меньше, чем запланировано в подзадачах. Выставили ue   . Если нужно уменьшить Расходы, уменьшите их у подзадач.r6   r   Fr   )r    r!   agregat_cost
const_costrj   r   r   r<   r   rr   r   r   r=   r>   r?   r   from_child_agregate_costr   r   r   rH   r   r   r   _do_sched_cost_is_changed  s     

z&CmfGanttTask._do_sched_cost_is_changedc                 C   s   |    d S r   rs   r_   r   r   r    _do_actual_start_date_is_changed  s    z-CmfGanttTask._do_actual_start_date_is_changedc                 C   s   |    d S r   r   r_   r   r   r   !_do_actual_finish_date_is_changed  s    z.CmfGanttTask._do_actual_finish_date_is_changedc                 C   sF   | j dkr|   n.| j dkr0| jjr0|   n| j dkrB|   d S )Nrx   ry   r{   r~   )r   r   r   rT   r   r   r_   r   r   r   #_do_actual_complete_type_is_changed  s    



z0CmfGanttTask._do_actual_complete_type_is_changedc                 C   s   | j r|   d S r   )rG   rn   r_   r   r   r   _do_const_duration_is_changed  s    z*CmfGanttTask._do_const_duration_is_changedc                 C   s*   | j rd| _| j| _n| jj| _d | _d S Nr8   )r   rA   r/   rB   defaultr_   r   r   r   $_do_lock_sched_start_date_is_changed  s
    

z1CmfGanttTask._do_lock_sched_start_date_is_changedc                 C   s*   | j rd| _| j| _n| jj| _d | _d S r   )r   rD   r0   rE   r   r_   r   r   r   %_do_lock_sched_finish_date_is_changed  s
    

z2CmfGanttTask._do_lock_sched_finish_date_is_changedc                 C   s  | j r^d| _d| _| jjrZ| jjj rZ| jjjj }|rLt|t	
 | _d| _|   d S | jjrr|   d S | jjr|   d S | jjs| jjr|   d S | jjs| jjr|   d S | jjr|   d S | jjr|   d S | jjr|   d S | jjr|   d S | jjr&|   d S | jjr<|    d S | j!jrR| "  d S | j#jrh| $  d S | j%jr~| &  d S | j'jr| (  d S | jjr| )  | j*dd d S | j+jr| ,  | j-dd d S | j.jr| /  d S | j0jr | 1  d S )Nr   r   r/   r   r0   )2Zis_newr*   r-   r   r   r=   r>   r/   rC   r1   ZutcnowrA   rw   r   r   r   r   r   rB   r   rE   rD   r   r   r   r   r   r   rz   r   r   r    r   ro   r   rp   r   r   r   rG   r   r   r   r0   r   r   r   r   r   r   )r   Zparent_sched_start_dater   r   r   _save  s    










zCmfGanttTask._savec                 C   sl   |  |   |   |  j|7  _| jdd |d kr\| j| j |kr\| j| | _|   | jdd d S )NTr   Z	only_data)	r?   r   fix_null_variablesr   r   r-   r   r   r   )r   r   Zremaining_estimater   r   r   timetracker_add_work_hook/  s    z&CmfGanttTask.timetracker_add_work_hookc                 C   s(  |rL|j dkrL| jsL| |   |   | j  |   | jdd d S |r|j dkr|r|j dkr| |   |   | j  d| _	| 
  |   | jdd |   d S |r$|j dkr$|r$|j dkr$| |   |   d | _d| _	| 
  |   | jdd |   d S d S )NZIN_PROGRESSTr   r}   r   r   )r   ro   r?   r   r   Zset_nowr   r   rp   rz   r   r   r   )r   Z
old_statusZ
new_statusr   r   r   task_status_is_changed_hook<  sF    

z(CmfGanttTask.task_status_is_changed_hookc                 C   s6   |  |   |   |   |   | jdd dS )u   
        В задаче изменились Agile-плановые даты, пересчитаем свои sched-даты, вдруг новые ограничения повлияют на них
        Tr   N)r?   r   r   r   r   r   r_   r   r   r   task_plan_dates_is_changed_hookc  s
    z,CmfGanttTask.task_plan_dates_is_changed_hookc                 C   s    | j jrd| _ |  j |7  _ d S r   )r   r!   )r   r   r   r   r   r   n  s    z CmfGanttTask.from_child_add_workc                 C   s    | j jrd| _ |  j |7  _ d S r   )r   r!   r   r   r   r   r   s  s    z CmfGanttTask.from_child_add_costc              	   C   s   | j jrd| _ |  j |7  _ | js,| j | _n2| j | jks^td| j  d| j d| j ddd | jjr| jjdkr| j jp|d| j j	pd }t
 8 | jjj }||   || |jd	d
 W 5 Q R X d S )Nr   u;   Превысили План на Трудозатраты ( <= +   ) в родительской задаче u_   . Увеличте в ней план или введите меньше ТрудозатратTrf   r6   Fr   )r   r!   r   r-   rj   r   r   r<   r   rr   r   r   r=   r>   r?   r   r   r   )r   r   rH   r   r   r   r   x  s     


z%CmfGanttTask.from_child_agregate_workc              	   C   s   | j jrd| _ |  j |7  _ | js,| j | _n2| j | jks^td| j  d| j d| j ddd | jjr| jjdkr| j jp|d| j j	pd }t
 8 | jjj }||   || |jd	d
 W 5 Q R X d S )Nr   u1   Превысили План на Расходы (r   r   uY   . Увеличте в ней план или введите меньше РасходовTrf   r6   Fr   )r   r!   r   r    rj   r   r   r<   r   rr   r   r   r=   r>   r?   r   r   r   r   r   r   r   r     s     


z%CmfGanttTask.from_child_agregate_costc                 C   s   |  | dS )u   
        Оповестить родителя, что ему нужно пересчитать свой агрегат actual_complete
        N)r   )r   r   r   r   r   !from_child_update_actual_complete  s    z.CmfGanttTask.from_child_update_actual_completec              	   C   sV   | j jsdS t 8 | j jj }||   ||  |j	dd W 5 Q R X dS )uP  
        Оповещение родителя.
        Передаем себя, т.к. мы еще можем быть не сохранены и родитель не сможет получить наши данные
        Другой вариант: опочещать через отдельный таск в celery
        NFr   )
r   r   r   r   r=   r>   r?   r   r   r   )r   rH   r   r   r   r     s    

z1CmfGanttTask.notify_parent_update_actual_completec                 C   s   | j jr| jjrtddd | jjr8| jjr8tddd | jjsH| jjrl| jrl| jrl| j| jk rltddd | jjr| jstddd | j	jr| jjs| j	dkrtddd d S )	Nu   Нельзя менять поле "Фактические трудозатраты" у Summary-задач. Используйте поле "Фактические трудозатраты по собственным ресурсам задачи"Trf   u   Нельзя менять поле "Фактические Затраты" у Summary-задач. Используйте поле "Фактические Затраты по собственным ресурсам задачи"u\   Нельзя выставить Дату начала позже Даты окончанияu   Будет доступно в версии Гант 2.0. Сейчас Вы можете использовать декомпозицию для множественных ресурсовr   u   Этот вариант рассчета процента завершения можно использовать только у Summary-задач)
r   r   r   rT   rj   r   rB   rE   r   r   r_   r   r   r   check_user_input  s*    zCmfGanttTask.check_user_inputc                 C   s   | j jrd| _ | jjrd| _| jjr*d| _| jjr8d| _| jjrFd| _| jjrTd| _| jjrbd| _| jjrpd| _| j	jr~d| _	| j
jrd| _
| jjrd| _| jjrd| _d S r   )r   r!   r   r    r   r*   rq   r   r-   r   rz   Zconstrain_slackZconstrain_slack_pctr_   r   r   r   r     s0    zCmfGanttTask.fix_null_variablesTr   c                   s@   |r|    |   | jjr*| jjdd |   t j||S )NTr   )r   r   r   r   r   r   r   )r   r   argskwargsr   r   r   r     s    zCmfGanttTask.save)N)F)F)F)F)N)N)5__name__
__module____qualname__classmethodr   r   propertyr'   r,   r.   r"   r@   rV   r`   rn   rs   rw   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   r   r   __classcell__r   r   r   r   r   	   sh   




$-
).
:2	4

!



(G
'
r   )
Zcmf.includeZdecimalr   r   r1   r   rh   Z
cmf.fieldsZ#modules.gantt.fields.cmf_gantt_taskr   r   r   r   r   <module>   s   