U
    =e                    @   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 fddZedxd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dyddZdd Zdzd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{d1d2Zd3d4 Zd|d5d6Zd7d8 Zd9d: Z d}d;d<Z!d=d> Z"d~d?d@Z#dAdB Z$dCdD Z%dEdF Z&dGdH Z'dIdJ Z(dKdL Z)dMdN Z*dOdP Z+dQdR Z,dSdT Z-dUdV Z.ddWdXZ/dYdZ Z0d[d\ Z1d]d^ Z2d_d` Z3dadb Z4dcdd Z5ddedfZ6dgdh Z7didj Z8dkdl Z9dmdn fdodp
Z:d0dq fdrds
Z; fdtduZ< fdvdwZ=  Z>S )r   c                    s   t  }ddddddddd	d
dddg}t jjd |j|d}|rT|D ]}|| ||< qB||_|  t  t j	|ddd W 5 Q R X |S )Nsched_start_datesched_finish_datesched_duration
sched_cost
sched_workconstrain_start_typeconstrain_start_dateconstrain_finish_typeconstrain_finish_dateprojectgantt_projecttaskparent_task)Z	parent_idtask_idfieldsFemitnotify)
modelsr   getidparentfix_null_variablescmfutildisable_notifysupersave)clsr   baseline
gantt_taskr   op_gantt_taskZfield	__class__ (./modules/gantt/models/cmf_gantt_task.py_create_gantt_task_for_baseline
   s*          
z,CmfGanttTask._create_gantt_task_for_baselineNc              	   C   sz   t  }|r| ||S |jr4|jjjdkr4|j|_|j  |j|_||_	|j
|_
t  |jddd W 5 Q R X |S )NZ
CmfProjectFr   )r   r   r*   r   value
class_namer   r   loadr   r   r   r   r!   )r"   r   r#   r$   r(   r(   r)   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)r    save_preload_fields)selfr   r&   r(   r)   r0   0   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)r
   is_null_perform_completeDecimalquantizer   r1   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 Nr2   1r3   )r	   r4   r5   r6   r7   r   intr8   r(   r(   r)   _perform_durationE   s
    zCmfGanttTask._perform_durationc                 C   s:   | j jrd S | j | j d }t|jtdtd}t|S r;   )r   r4   r5   r6   r7   r   r=   r8   r(   r(   r)   _perform_workM   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   r2   r<   r3   )r   r4   r   datetimeZnowtimezoneZutcZtotal_secondsr=   r6   r7   r   )r1   Zdelta_now_time_secZdelta_finish_time_secZperform_completer9   r(   r(   r)   r5   U   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)rD   2-before)r   r   logic_prefixr%   r-   load_fieldsr0   get_parent_plan_limitr   r   maxr   r   minconst_durationr	   )r1   Zparent_start_limitZparent_finish_limitZparent_duration_limitparent_gantt_taskstart_limitfinish_limitduration_limitr(   r(   r)   rI   n   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 )NrB   task.parent_task=filterr   )rD   4-before)rD   1-after)r   has_child_tasksr   r   listr0   r   r   rK   r   r   rJ   rL   rP   get_childrens_plan_limit)r1   rN   rO   rP   r$   Zch_start_limitZch_finish_limitZch_duration_limitr(   r(   r)   rY      sH    




z%CmfGanttTask.get_childrens_plan_limitc                 C   sB   t | ddrd S d| _|  \| _| _| _|  \| _| _| _	d S )N_calc_plan_limits_cache_doneFT)
getattrrZ   rI   _plan_start_limit_min_plan_finish_limit_max_plan_duration_limit_maxrY   _plan_start_limit_max_plan_finish_limit_min_plan_duration_limit_minr1   r(   r(   r)   _calc_plan_limits_cache   s    z$CmfGanttTask._calc_plan_limits_cachec                 C   sF   | j r,| jr,tj|  | j j| jj| _n| j jrB| jjrBd| _d S Nr   )	r   r   r   CmfCalendarget_duration_minutes_get_calendarr+   r	   oldrb   r(   r(   r)   _calc_sched_duration   s      z!CmfGanttTask._calc_sched_durationc                 C   sF   | j r,| jr,tj|  | j j| jj| _n| j jrB| jjrBd| _d S rd   )	actual_start_dateactual_finish_dater   re   rf   rg   r+   actual_durationrh   rb   r(   r(   r)   _calc_actual_duration   s      z"CmfGanttTask._calc_actual_durationc                 C   s  | j js| j dkrd | _d S | jjr0| jjr0d S | jr| jdkr|dkrtj|  | jj	t
| j }| jj	}| jdkr|r||k rtd|dddd	 | jd
kr|r||krtd|dddd	 || _d S | jr| jdkr|dkrtj|  | jj	t
| j  }| jj	}| jdkrH|rH||k rHtd|dddd	 | jdkrz|rz||krztd|dddd	 || _d S | jdkr| jdkr| jrtd d S )Nr   rD   
start_daterV   um   Плановая дата окончания раньше ограничения даты окончания %d.%m.%Yu   . Увеличьте длительность или измените плановую дату начала на более позднюю.TabortrF   uk   Плановая дата окончания позже ограничения даты окончания u   . Уменьшите длительность или измените плановую дату начала на более раннюю.finish_daterE   ua   Плановая дата начала раньше ограничения даты начала u   . Уменьшите длительность или измените плановую дату окончания на более позднюю.rU   u_   Плановая дата начала позже ограничения даты начала u   . Увеличьте длительность или измените плановую дату окончания на более раннюю.u   Плановый период может не соответствовать плановой длительности, т.к. все переменные зафиксированы)r	   r4   r   r   r   r   re   get_date_by_durationrg   r+   r=   r   	cmf_alertr   r   rL   )r1   offsetr   r   r   r   r(   r(   r)   _calc_sched_period   sr      

  
 zCmfGanttTask._calc_sched_periodc                 C   s   | j js| j dkrd | _d S | jjr0| jjr0d S | jrZtj|  | jjt	| j | _d S | jrtj|  | jjt	| j  | _d S d S rd   )
rl   r4   rk   rj   r   re   rs   rg   r+   r=   rb   r(   r(   r)   _calc_actual_period%  s&        
z CmfGanttTask._calc_actual_periodc           
      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-completerQ   rR   actual_completerS   r   2-story_pointsr   agile_story_pointszstatus.status_typeCLOSEDr2   3-costz4-fixed)r   rW   actual_complete_typer   r   rX   lenr   rz   r+   CmfTaskrH   r|   statusstatus_type)
r1   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_complete9  sR    

z+CmfGanttTask._calc_summarry_actual_completec                 C   sv  |    |   | jdkr,| j| _d| _n| jdkr| j}| jrV| jrVt| j| j}|r| jrj| j|k r| jrtd|j	dd || _n| jdkr| j}| jr| j
rt| j| j
}|r| jr| j|kr| jrtd|j	dd || _nN| js| j| _| jr| jrt| j| j| _| jr:| j
r:t| j| j
| _| j
rd| jrd| j| j
krdtd	dd
 | jr| jr| j| jk rtddd
 | jjr8| j
r| jj| j
k r8| jr| jj| jkr8| js| jj| _n\| jdkrnN| jdkr| jj| jk r8| jj| _n&| jdkr8| jj| jkr8| jj| _| jr^| jr^| js^| jdd n|    | jdd d S )NrD   TrE   uA   Плановая дата начала перемещена на ro   uR   , так как была раньше ограничения даты началаrU   uP   , так как была позже ограничения даты началаu~   Нельзя указать Дату начала больше зафиксированной у дочерней задачиrp   u   Нельзя указать Дату начала меньше зафиксированной у родительской задачи)1-earlyrU   )z2-latterrE   rr   ru   r   
date_field)ri   rc   r   r   r   lock_sched_start_dater\   rJ   rt   r+   r_   rK   r   Zplan_start_dater	   lock_sched_finish_daterv   _change_parent_start_date)r1   r   r(   r(   r)   #_do_constrain_start_date_is_changeds  sl    





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 )Nr   r   r   r   r   r   rC   r   rR   r   r/   z!=rS   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   rG   parent_task_idr   r   rX   ZCmfRelationOptionmap)
r1   Znormal_parentsr#   r   rT   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   s6   d }|  ddg | jr | jj}|p4tjjddgdS )Nzproject.calendarzproject.calendar.timezonezsystem:defaultrA   )coder   )rH   r   calendarr   re   r   )r1   r   r(   r(   r)   rg     s
    zCmfGanttTask._get_calendarc                 C   s   | j dkr| jrtddd | jrT| jrT| jdkrT| jjrT| jj| jk rTtddd | jr| jr| jdkr| jjr| jj| jkrtddd | jr| jr| js| j	d	d
 n| 
  d S )NrD   u   Нельзя менять дату начала, если зафиксирована дата окончания и длительностьTrp   rE   ua   Ошибка: Плановая дата начала меньше даты ограниченияrU   ua   Ошибка: Плановая дата начала больше даты ограниченияrr   r   )r   rL   rt   r   r   r   newr	   r   rv   ri   rb   r(   r(   r)   _do_sched_start_date_is_changed  s"    z,CmfGanttTask._do_sched_start_date_is_changedc                 C   s   | j dkr| jrtddd | jrN| jdkrN| jjrN| jj| jk rNtddd | jr| jdkr| jjr| jj| jkrtddd | jr| jr| jr| j	d	d
 n| 
  d S )NrD   u   Нельзя менять дату окончания, если зафиксирована дата начала и длительностьTrp   rV   ug   Ошибка: Плановая дата окончания меньше даты ограниченияrF   ug   Ошибка: Плановая дата окончания больше даты ограниченияrn   r   )r   rL   rt   r   r   r   r   r	   r   rv   ri   rb   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 )NrD   ^   Дата родительской задачи является зафиксированнойrU   u   Предупреждение: Плановая дата начала дочерней задачи больше плановой даты начала родительской задачиrE   u   Предупреждение: Плановая дата начала дочерней задачи меньше плановой даты начала родительской задачиr   )r   r   rt   r!   r   )r1   r   parentsrM   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 |jr||jkr|j}|||< |  || q| jdk| _d S )NrD   r   rV   u   Предупреждение: Плановая дата окончания дочерней задачи меньше плановой даты окончания родительской задачиrF   u   Предупреждение: Плановая дата окончания дочерней задачи больше плановой даты окончания родительской задачи)r   r   rt   r   r!   _change_parent_finish_dater   r   )r1   r   r   rM   Z
date_valuer(   r(   r)   r     s,    
 z'CmfGanttTask._change_parent_finish_datec                 C   sn  |    |   | jdkr,| j| _d| _n| jdkr| j}| jrV| jrVt| j| j}|r| jrj| j|k r| jrtd|j	dd || _n| jdkr| j}| jr| jrt
| j| j}|r| jr| j|kr| jrtd|j	dd || _nN| js| j| _| jr| jrt| j| j| _| jr:| jr:t
| j| j| _| jr| jrd| j| jkrdtd	dd
 | jr| j| jk rtddd
 | jjr0| jr| jj| jk r0| jr| jj| jkr0| js| jj| _n\| jdkrnN| jdkr
| jj| jkr0| jj| _n&| jdkr0| jj| jk r0| jj| _| jrV| jrH| jrV| jdd n|    | jdk| _d S )NrD   TrV   uG   Плановая дата окончания перемещена на ro   uX   , так как была раньше ограничения даты окончанияrF   uV   , так как была позже ограничения даты окончанияu   Нельзя указать Дату окончания больше зафиксированной у родительской задачиrp   u   Нельзя указать Дату окончания меньше зафиксированной у дочерней задачиrn   r   )ri   rc   r   r   r   r   r`   rJ   rt   r+   rK   r]   r   Zplan_end_dater	   r   rL   rv   )r1   r   r(   r(   r)   $_do_constrain_finish_date_is_changed(  sn    





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	r| j| _
| jdd | j	r| j| j
k rtddd | jd	d
 d S )NrD   u   Нельзя менять длительность, если зафиксирована дата начала и дата окончанияTrp   u   Нельзя указать Длительность больше зафиксированной у родительской задачиu   Нельзя указать Длительность меньше зафиксированной у дочерней задачи)from_sched_duration_changedu   Нельзя указать Длительность меньше чем Трудозатраты, когда установлена опция Фиксированные Ресурсы и Трудозатраты зафиксированыr   r   )r   r   rt   rc   r^   r	   ra   rv   
const_workconst_resourcer   _do_sched_work_is_changedr   )r1   from_sched_work_changedr(   r(   r)   _do_sched_duration_is_changedj  s"    
z*CmfGanttTask._do_sched_duration_is_changedc                 C   s   |    d S r   )rw   rb   r(   r(   r)   _do_actual_duration_is_changed  s    z+CmfGanttTask._do_actual_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   "Фактические трудозатраты" стал ниже нуля, выставляем в ноль.Trp   rx   r2   rC   F
user_input)actual_workr4   rt   r   rW   actual_myself_workr   r   is_not_nullmathfloorrK   rz   $notify_parent_update_actual_completer   rh   r   rG   r   disable_aclr%   r-   rH   r0   from_child_add_workr!   
is_changedr   ZCmfTimeTrackerZ"_op_gantt_actual_work_changed_hook)r1   from_timetrackertmp_complete
work_deltarM   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   "Фактические Затраты" стал ниже нуля, выставляем в ноль.Trp   r~   r2   rC   Fr   )actual_costr4   rt   r   r
   r   r   r   rK   rz   r   r   r   rG   r   rh   r   r   r%   r-   rH   r0   from_child_add_costr!   )r1   r   
cost_deltarM   r(   r(   r)   _do_actual_cost_is_changed  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   r4   r   rb   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   rh   r   rW   r   r   )r1   r   r   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 rd   )actual_myself_costr   rh   r   rW   r   r   r1   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rb| j | jk r| jrFtd| j  d| j ddd q| j| _ td| j d nH|s| j r| js| jr| 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 : | jjj }||   || |jddd W 5 Q R X d S )Nu   Нельзя запланировать меньше Трудозатрат, чем запланировано в подзадачах ( < u`   ). Увеличте Трудозатраты или уменьшите их у подзадач.Trp   u   Указано Трудозатрат меньше, чем запланировано в подзадачах. Выставили uo   . Если нужно уменьшить Трудозатраты, уменьшите их у подзадач.)r   u   Нельзя указать Трудозатраты больше чем Длительность, когда установлена опция Фиксированные Ресурсы и Длительность зафиксированаrC   r   Fr   	only_data)r   r4   r   rW   agregat_workr   rt   rL   r   r	   r   r   rG   r   rh   r   r   r%   r-   rH   r0   from_child_agregate_workr!   )r1   r   r   rM   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
 : | jjj }||   || |jd
dd W 5 Q R X d S )Nu   Нельзя запланировать меньше Расходов, чем запланировано в подзадачах (r   uX   ). Увеличте Расходов или уменьшите их у подзадач.Trp   u|   Указано Расходов меньше, чем запланировано в подзадачах. Выставили ue   . Если нужно уменьшить Расходы, уменьшите их у подзадач.rC   r   Fr   )r
   r4   agregat_cost
const_costrt   r   r   rG   r   rh   r   r   r%   r-   rH   r0   from_child_agregate_costr!   r1   r   rM   r(   r(   r)   _do_sched_cost_is_changed  s     

z&CmfGanttTask._do_sched_cost_is_changedc                 C   s"   | j r| jr|   n|   d S r   )rj   rl   rw   rm   rb   r(   r(   r)    _do_actual_start_date_is_changed  s    
z-CmfGanttTask._do_actual_start_date_is_changedc                 C   s(   | j s| jr| jr|   n|   d S r   )rj   rk   rl   rw   rm   rb   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   rW   r   r   rb   r(   r(   r)   #_do_actual_complete_type_is_changed)  s    



z0CmfGanttTask._do_actual_complete_type_is_changedc                 C   s   | j r|   d S r   )rL   ri   rb   r(   r(   r)   _do_const_duration_is_changed5  s    z*CmfGanttTask._do_const_duration_is_changedc                 C   s*   | j rd| _| j| _n| jj| _d | _d S NrD   )r   r   r   r   defaultrb   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   r   r   r   r   rb   r(   r(   r)   %_do_lock_sched_finish_date_is_changedC  s
    

z2CmfGanttTask._do_lock_sched_finish_date_is_changedc           	   	   C   s   | j }| j}| j}| j}t  | jj}|r|j	 }|
|   ||  ||  ||  ||  |jdd | jj}|r|j	 }|
|   || || || || |jdd W 5 Q R X d S )NFr   )r
   r   r   r   r   r   r   rh   r%   r-   rH   r0   r   r   r   r   r!   r   )	r1   r
   r   r   r   Z
old_parentZold_parent_gantt_taskZ
new_parentZnew_parent_gantt_taskr(   r(   r)   _do_parent_task_is_changedK  s.    






z'CmfGanttTask._do_parent_task_is_changedc                 O   s   t jj| df|| d S )Nupdated)r   ZCmfEventZdo_event)r1   argskwargsr(   r(   r)   _do_event_savei  s    zCmfGanttTask._do_event_savec                 O   s
   | | j S r   )Z	log_level)r1   Z
field_namer   r   r(   r(   r)   _get_field_log_levell  s    z!CmfGanttTask._get_field_log_levelc                 C   s0  | 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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rR| !  d S | j"jrh| #  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| ,  | j-dd d S | j.jr| /  | j0dd d S | j1jr| 2  d S | j3jr,| 4  d S )Nr   r   r   r   r   )5is_newr	   r   r   r   r%   r-   r   rJ   r@   Zutcnowr   rv   r   r   r   r   r   r   r   r   r   r   r   r   rl   r   r   r   r   r   rz   r   r   r
   r   rj   r   rk   r   r   r   rL   r   r   r   r   r   r   r   r   r   r   )r1   Zparent_sched_start_dater(   r(   r)   _savep  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   r   )	rH   r0   r   r   r   r   r   r   r!   )r1   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}   r2   r   )r   rj   rH   r0   r   Zset_nowr   r!   rk   rz   r   r   r   )r1   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)rH   r0   r   r   r   r!   rb   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 rd   )r   r4   )r1   r   r(   r(   r)   r     s    z CmfGanttTask.from_child_add_workc                 C   s    | j jrd| _ |  j |7  _ d S rd   )r   r4   r   r(   r(   r)   r     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_   . Увеличте в ней план или введите меньше ТрудозатратTrp   rC   Fr   )r   r4   r   r   rt   r   r   rG   r   rh   r   r   r%   r-   rH   r0   r   r!   )r1   r   rM   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   . Увеличте в ней план или введите меньше РасходовTrp   rC   Fr   )r   r4   r   r
   rt   r   r   rG   r   rh   r   r   r%   r-   rH   r0   r   r!   r   r(   r(   r)   r     s     


z%CmfGanttTask.from_child_agregate_costc                 C   s   |  | dS )u   
        Оповестить родителя, что ему нужно пересчитать свой агрегат actual_complete
        N)r   )r1   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-   rH   r0   r   r!   )r1   rM   r(   r(   r)   r   4  s    

z1CmfGanttTask.notify_parent_update_actual_completec                 C   s  | j sp| jrpdd | jddD }|ddddh }|rp| jj  | jjrp| jjjjd	rp| jjj	d
| jd | j
jr| jjrtddd | jjr| jjrtddd | jjs| jjr| jr| jr| j| jk rtddd | jjr| jjs| jdkrtddd d S )Nc                 S   s   h | ]\}}|qS r(   r(   ).0k_r(   r(   r)   	<setcomp>G  s     z0CmfGanttTask.check_user_input.<locals>.<setcomp>T)r   r   r   r   Zgantt_project_idzCmfProject:zPPP-TSK-SCHEDULE)obju   Нельзя менять поле "Фактические трудозатраты" у Summary-задач. Используйте поле "Фактические трудозатраты по собственным ресурсам задачи"rp   u   Нельзя менять поле "Фактические Затраты" у Summary-задач. Используйте поле "Фактические Затраты по собственным ресурсам задачи"u\   Нельзя выставить Дату начала позже Даты окончанияr   u   Этот вариант рассчета процента завершения можно использовать только у Summary-задач)r   r   itemsr   Zroot_parentr-   r   r+   
startswithZcheck_project_role_accessr   rW   rt   r   r   r   r   )r1   Zchanged_fieldsr(   r(   r)   check_user_inputE  s0    
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 rd   )r   r4   r   r
   r   r	   rl   r   r   r   rz   Zconstrain_slackZconstrain_slack_pctrb   r(   r(   r)   r   ^  s0    zCmfGanttTask.fix_null_variablesTr   c                   sL   |r|    | j|| |   | jjr6| jjdd |   t j||S )NTr   )r   r   r   r   r   r!   r   r    )r1   r   r   r   r&   r(   r)   r!   y  s    zCmfGanttTask.save)TEXKOM_db_deletec                   s   |  ddg |rTt| j tjj| jddD ] }t| d |_|jdd q0n&| j	rz| j	j| krz| j	j
sztddd t j|d|i|S )	Nztask.op_gantt_taskztask.cmf_deletedT)r%   Zinclude_deletedr   uY   Нельзя удалять Оперативную гант задачу у задачи!rp   r   )rH   gdebugr   r   r   rX   r%   r!   r   Zcmf_deletedrt   r    delete)r1   r   r   r   r   r&   r(   r)   r     s    
zCmfGanttTask.deletec                    sB   t  jf | | jrd S td tj| jdd td d S )N_CmfAutomationCrudTrigger startupdateZbefore_save_CmfAutomationCrudTrigger end)	r    before_save_hookr   r   r   r   CmfAutomationCrudTrigger	crud_hookr   r1   r   r&   r(   r)   r     s    
zCmfGanttTask.before_save_hookc                    sB   t  jf | | jrd S td tj| jdd td d S )Nr   r   Z
after_saver   )	r    before_save_data_hookr   r   r   r   r   r   r   r   r&   r(   r)   r     s    
z"CmfGanttTask.before_save_data_hook)N)N)N)F)F)F)F)N)N)?__name__
__module____qualname__classmethodr*   r.   r0   propertyr:   r>   r?   r5   rI   rY   rc   ri   rm   rv   rw   r   r   r   rg   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   r!   r   r   r   __classcell__r(   r(   r&   r)   r   	   s~   



$-
	
=
:@	B

!



(M
'

r   )
Zcmf.includeZdecimalr   r   r@   r   r   Z
cmf.fieldsZ#modules.gantt.fields.cmf_gantt_taskr   r(   r(   r(   r)   <module>   s   