U
    8c"                     @   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                       sJ  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dd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!d;d< Z"d=d> Z#d?d@ Z$dAdB Z%dCdD Z&dEdF fdGdH
Z'  Z(S )Ir   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   Z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   z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datetimeZ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)r4   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 )Nr2   ztask.parent_task=)filterr   )r4   4-before)r4   1-after)r   has_child_tasksr	   r   listr   r<   r=   rA   r?   r@   r>   rB   rF   get_childrens_plan_limit)r   rD   rE   rF   r   Zch_start_limitZch_finish_limitZch_duration_limitr   r   r   rM   {   sH    




z%CmfGanttTask.get_childrens_plan_limitc                 C   sB   t | ddrd S d| _|  \| _| _| _|  \| _| _| _	d S )N_calc_plan_limits_cache_doneFT)
getattrrN   r;   _plan_start_limit_min_plan_finish_limit_max_plan_duration_limit_maxrM   _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   sd   | j r| jjrd S | jr`| jr`| j| j }| d d d }tt|d d}|d d | _d S )N<      着&?      )	rB   r(   is_not_nullr-   r.   r1   r>   mathceilr   ZdeltaZ
delta_days	work_daysr   r   r   _calc_sched_duration   s    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 )NrX   rY   rZ   r[   r\   r   )actual_start_dateactual_finish_dater1   r>   r^   r_   actual_durationoldr`   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kr`| jr| j d d }t|d }| jt|d | _n>| jdkr| jr| j d d }t|d }| jt|d | _| jdkr| jdkr| j	rt
d d S )Nr4   r\   rX   rZ   )Zdaysu   Плановый период может не соответствовать плановой длительности, т.к. все переменные зафиксированы)r(   r   r-   r.   r?   r^   r_   r   r<   rB   	cmf_alert)r   ra   Zcalendar_daysr   r   r   _calc_sched_period   s     

zCmfGanttTask._calc_sched_periodc                 C   s  |    | jdkr| j| _n| jdkrL| 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| jkrtddd | jr| j| jk rtddd | j	j
r| jr| j	j
| jk r| jr2| 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r|   d S )
Nr4   r5   rI   u~   Нельзя указать Дату начала больше зафиксированной у дочерней задачиTabortu   Нельзя указать Дату начала меньше зафиксированной у родительской задачи)1-earlyrI   )z2-latterr5   )rW   r<   r=   r-   rP   r>   rS   rA   rh   r   Zplan_start_daterb   r(   ri   rV   r   r   r   #_do_constrain_start_date_is_changed   sT    





z0CmfGanttTask._do_constrain_start_date_is_changedc                 C   s  |    | jdkr| j| _n| jdkrL| 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| jkrtddd | jr| j| jk rtddd | j	j
r| jr| j	j
| jk r| jr2| 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
| _|   d S )Nr4   rJ   r6   u   Нельзя указать Дату окончания больше зафиксированной у родительской задачиTrj   u   Нельзя указать Дату окончания меньше зафиксированной у дочерней задачи)rW   r?   r@   r.   rT   r>   rQ   rA   rh   r   Zplan_end_daterb   rV   r   r   r   $_do_constrain_finish_date_is_changed  sP    





z1CmfGanttTask._do_constrain_finish_date_is_changedc                 C   sp   | 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 |   d S )Nr4   u   Нельзя менять длительность, если зафиксирована дата начала и дата окончанияTrj   u   Нельзя указать Длительность больше зафиксированной у родительской задачиu   Нельзя указать Длительность меньше зафиксированной у дочерней задачи)r<   r?   rh   rW   rR   r(   rU   ri   rV   r   r   r   _do_sched_duration_is_changedC  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rl| jdkrlt| j | j d }t|d}| jjsf|| jkrl|| _| 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   uo   "Фактические трудозатраты" стал ниже нуля, выставляем в ноль.Trj   r   r3   F
user_input)actual_workr   rh   r+   r]   r^   ZfloorrA   actual_completer   r   r7   newrf   r   disable_aclr8   r9   r:   r   from_child_add_workr   )r   Ztmp_complete
work_deltarC   r   r   r   _do_actual_work_is_changedO  s     



z'CmfGanttTask._do_actual_work_is_changedc              	   C   s   | j jrd S | j dk r"tddd | jjr| jjdkr| j jp@d| j jpJd }t	 8 | jjj
 }||   || |jdd W 5 Q R X d S )Nr   ue   "Фактические Затраты" стал ниже нуля, выставляем в ноль.Trj   r3   Frp   )actual_costr   rh   r   r   r7   rt   rf   r   ru   r8   r9   r:   r   from_child_add_costr   r   
cost_deltarC   r   r   r   _do_actual_cost_is_changedd  s    


z'CmfGanttTask._do_actual_cost_is_changedc                 C   sD   | j jrd S | jjrd S | j | j d }| jjs:|| jkr@|| _d S )Nr   )r+   r   rs   rr   )r   Ztmp_actual_workr   r   r   _do_actual_complete_is_changedr  s    z+CmfGanttTask._do_actual_complete_is_changedc                 C   sD   | j jp
d| j jpd }| jjs*| j | _n|  j|7  _|   d S Nr   )actual_myself_workrt   rf   r   rK   rr   rx   r   rw   r   r   r   !_do_actual_myself_work_is_changed{  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 r   )actual_myself_costrt   rf   r   rK   ry   r}   r   r|   r   r   r   !_do_actual_myself_cost_is_changed  s
    
z.CmfGanttTask._do_actual_myself_cost_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   Нельзя запланировать меньше Трудозатрат, чем запланировано в подзадачах ( < u`   ). Увеличте Трудозатраты или уменьшите их у подзадач.Trj   u   Указано Трудозатрат меньше, чем запланировано в подзадачах. Выставили uo   . Если нужно уменьшить Трудозатраты, уменьшите их у подзадач.r3   r   Frp   )r+   r   agregat_work
const_workrh   r   r   r7   rt   rf   r   ru   r8   r9   r:   r   from_child_agregate_workr   r   rw   rC   r   r   r   _do_sched_work_is_changed  s     

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   ). Увеличте Расходов или уменьшите их у подзадач.Trj   u|   Указано Расходов меньше, чем запланировано в подзадачах. Выставили ue   . Если нужно уменьшить Расходы, уменьшите их у подзадач.r3   r   Frp   )r   r   agregat_cost
const_costrh   r   r   r7   rt   rf   r   ru   r8   r9   r:   r   from_child_agregate_costr   r{   r   r   r   _do_sched_cost_is_changed  s     

z&CmfGanttTask._do_sched_cost_is_changedc                 C   s   |    d S Nrg   rV   r   r   r    _do_actual_start_date_is_changed  s    z-CmfGanttTask._do_actual_start_date_is_changedc                 C   s   |    d S r   r   rV   r   r   r   !_do_actual_finish_date_is_changed  s    z.CmfGanttTask._do_actual_finish_date_is_changedc                 C   sf  | j rXd| _| jjrT| jjj rT| jjjj }|rFt|t	 | _d| _
|   d S | jjrl|   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r6|    d S | j!jrL| "  d S | j#jrb| $  d S d S )Ni  rl   )%Zis_newr(   r   r   r8   r9   r-   r>   r/   Zutcnowr<   ri   r   
is_changedr   r   r   r=   rm   r@   r?   rn   ro   rr   rx   ry   r}   rs   r~   r+   r   r   r   rc   r   rd   r   )r   Zparent_sched_start_dater   r   r   _save  sZ    




zCmfGanttTask._savec                 C   s    |  |   |  j|7  _d S r   )r:   r   r   r   r   r   r   timetracker_add_work  s    z!CmfGanttTask.timetracker_add_workc                 C   s   |rD|j dkrD| jsD| |   | 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_progressTZ	only_dataclosedr   r   )Zstatus_typerc   r:   r   Zset_nowr   r   rd   rs   r   r~   )r   Z
old_statusZ
new_statusr   r   r   task_status_is_changed_hook  s<    

z(CmfGanttTask.task_status_is_changed_hookc                 C   s.   |  |   |   |   | jdd dS )u   
        В задаче изменились Agile-плановые даты, пересчитаем свои sched-даты, вдруг новые ограничения повлияют на них
        Tr   N)r:   r   rm   rn   r   rV   r   r   r   task_plan_dates_is_changed_hook  s    z,CmfGanttTask.task_plan_dates_is_changed_hookc                 C   s    | j jrd| _ |  j |7  _ d S r   )rr   r   r   r   r   r   rv   $  s    z CmfGanttTask.from_child_add_workc                 C   s    | j jrd| _ |  j |7  _ d S r   )ry   r   r   r   r   r   rz   )  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_   . Увеличте в ней план или введите меньше ТрудозатратTrj   r3   Frp   )r   r   r   r+   rh   r   r   r7   rt   rf   r   ru   r8   r9   r:   r   r   r   r   r   r   r   r   .  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   . Увеличте в ней план или введите меньше РасходовTrj   r3   Frp   )r   r   r   r   rh   r   r   r7   rt   rf   r   ru   r8   r9   r:   r   r   r   r{   r   r   r   r   B  s     


z%CmfGanttTask.from_child_agregate_costc                 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 d S )Nu   Нельзя менять поле "Фактические трудозатраты" у Summary-задач. Используйте поле "Фактические трудозатраты по собственным ресурсам задачи"Trj   u   Нельзя менять поле "Фактические Затраты" у Summary-задач. Используйте поле "Фактические Затраты по собственным ресурсам задачи"u\   Нельзя выставить Дату начала позже Даты окончанияu   Будет доступно в версии Гант 2.0. Сейчас Вы можете использовать декомпозицию для множественных ресурсов)	rr   r   r   rK   rh   ry   r=   r@   Zconst_resourcerV   r   r   r   check_user_inputV  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| _| jjrd| _d S r   )rr   r   r   r   ry   r(   re   r   r+   r   rs   Zconstrain_slackZconstrain_slack_pctrV   r   r   r   fix_null_variablesf  s4    zCmfGanttTask.fix_null_variablesTrp   c                   sZ   |r|    |   | jjr.| jjr.| j| j_| jjrD| jjdd |   t	 j||S )NTr   )
r   r   r+   r]   r   r   Ztime_estimater   r   r   )r   rq   argskwargsr   r   r   r     s    
zCmfGanttTask.save))__name__
__module____qualname__classmethodr   r   propertyr%   r*   r,   r    r;   rM   rW   rb   rg   ri   rm   rn   ro   rx   r}   r~   r   r   r   r   r   r   r   r   r   r   rv   rz   r   r   r   r   r   __classcell__r   r   r   r   r   	   sP   




$-
1/	

3"
r   )
Zcmf.includeZdecimalr   r   r/   r   r^   Z
cmf.fieldsZ#modules.gantt.fields.cmf_gantt_taskr   r   r   r   r   <module>   s   