
    fiN                     T    d dl T d dlmZ d dlmZmZmZ  G d dej                  ZdS )    )*)cmf_relation_option)defaultdictdeque
namedtuplec                        e Zd ZdZ fdZ fdZe edddgdd          dd                        Zd Z	d Z
defdZd Z fdZd Zd ZddZd Zd Zedd            Z xZS )CmfRelationOptionuN    Класс для соединения задач и типов связей c                    t           j                            | dd           | j        | j        k    rt          dd           dd| j        gdd	| j        gd
d	| j        gdd	| j        gg}t           j        	                    |          rt          dd           | j
        j        dv rt           j        	                    g dd
d| j        | j        ggdd| j        | j        ggg          rt          dd           |                     g d           |                                 rt          dd           |                                 rt          dd           | j
        j        dk    r|                     g d           | j        j        | j        k    s| j        j        | j        k    rt          dd           |                                 rt          dd           t           j        	                    ddddggd
d| j        | j        ggdd| j        | j        ggg          rt          dd           |                                   t%                      j        |i |}t           j                            | dd           | j
        j        dk    r| j        j                                         | j
        j        dv rx| j        s| j        j        re|                    dd          sO| j        j        j        r>| j        j        j        r-t9          t           j        j        | j        j        d d!"           t           j                            |            |S )#Nupdatebefore_saveuV   Внимание! Нельзя связывать задачу саму с собой!Tabortidz!=out_link==in_linkrelation_type_idfilteru2   Такая связь уже существует.)system.finish:startsystem.finish:finish)relation_type.coder   system.additional_parentINu   Невозможно связать задачи связью ОО/ОН, так как они связаны связью Дополнительный родитель/Дополнительная дочерняя задача.)+in_link.parent_task.cache_branch_gantt_path,out_link.parent_task.cache_branch_gantt_pathz'out_link.op_gantt_task.sched_start_datez(out_link.op_gantt_task.sched_finish_dateum   Невозможно связать суммарную задачу с одной из ее подзадач.u   Невозможно связать задачи, так как они уже связаны через другую последовательность задач.r   )in_link.op_gantt_taskout_link.op_gantt_taskr   z out_link.cache_branch_gantt_pathzout_link.has_child_tasksr   zin_link.cache_branch_gantt_pathin_link.has_child_tasksu  Невозможно связать задачи связью Дополнительный родитель/Дополнительная дочерняя задача, так как они являются родительской и дочерней задачами.u  Невозможно связать задачи связью Дополнительный родитель/Дополнительная дочерняя задача, так как они связаны через другую последовательность задач.r   r   r   u   Невозможно связать задачи связью Дополнительный родитель/Дополнительная дочерняя задача, так как они связаны связью ОО/ОН.
after_savefrom_task_copyFcreate)task_idaction)kwargs) modelsCmfAutomationCrudTrigger	crud_hookr   r   	cmf_alertr   r   r	   sgetrelation_typecodeload_fieldshas_parent_child_relationshas_start_finish_loopparent_taskhas_additional_parent_loop'_check_additional_parent_task_relationssupersaveop_gantt_task*additional_children_relations_changed_hookis_newconstrain_lag
is_changedgetsched_start_datesched_finish_dateschedule_deferred_jobsort_task_by_order_relationsCmfBackbonePeerobj_after_save_hook)selfargsr%   duplicate_filterres	__class__s        ,./modules/task/models/cmf_relation_option.pyr4   zCmfRelationOption.save
   s   '11$-PPPMT\))nvz{{{{ 4!t}-dl+t'<=	
 #((0@(AA 	XJRVWWWW"&UUU',,5m5m5m6?W[WcGd5ehrtx{  |I  KO  KW  {X  hY5Z, [ [ S F NRS S S S        ..00 W  J  RV  W  W  W  W))++ O  B  JN  O  O  O  O"&@@@ 	 	 	 	 	 	 }(DL88DL<TX\Xe<e<e A IMN N N N ..00 V I QUV V V V ',,6JDSh  kA  SB  6C6?W[WcGd5ehrtx{  |I  KO  KW  {X  hY5Z, [ [ e X_ce e e e 88:::egglD+F++'11$,OOO"&@@@L&QQSSS#'VVV W $ 2 = WJJ/77 W }*; V@[@m V$V%=%Zoso|o  LT  dU  dU  V  V  V  V224888
    c                    t           j                            | dd           |                     dg            t	                      j        |i |}| j        j        dk    r4|                     dg           | j        j	        
                                 t           j                            | dd           t           j                            |            |S )Ndeleter   r+   r   r   r    )r&   r'   r(   r-   r3   rI   r+   r,   r   r5   r6   r?   obj_after_delete_hook)rA   rB   r%   rD   rE   s       rF   rI   zCmfRelationOption.deleteU   s    '11$-PPP/*+++eggnd-f--"&@@@'    L&QQSSS'11$,OOO44T:::
rG   Tr#      uc   Вычисление плановых дат у задач от выставленной связи)	only_onceshow_bg_progressbaronly_once_argsprioritydescriptionNr   c           
         | d S |st                      }| |v rd S |                    |            t          j                            dd| gg d          }|sd S t
                              d|j        j         d|j	        j         d|j
        j         d|            |j
        j        }|sd S |j        j        }t          j                            d	d
ddggdd|ggg d          }|D ]}|j        }	|	j
        }
|
                    |
                                           |
j        r|dk    r|dk    sLt)          |j        j        pd          }|j        j	        dk    r+|j        }|r!t          j                            |||          }nE|j        j	        dk    r4|
j        |z   pd}t          j                            ||j        |           }n|
                    |d          }||
j        k    r||
_        |
j        j        r||
j        j        k     r|
                                rD|
                    d           |dz  dk    rt?                       t          j                             |	j!        j        ||dz              d S )Nr   r   )r5   zop_gantt_task.sched_finish_datezproject.calendar.timezoner   fieldsz,sort_task_by_order_relations start task_id: z (z), sched_finish_date z	, depth: r   r   r   r   r   )r   r   r8   r   r   r"   T)return_correct_date)from_sort_order
   rK   )pathdepth)"setaddr&   CmfTaskr:   gdebugnamevaluer,   r5   r<   projectcalendarr	   listr   r-   save_preload_fields	is_manualintr8   r+   CmfCalendarget_date_by_durationsched_durationcheck_correct_start_dater;   old _get_task_blocking_back_movementr4   
cmf_commitr>   r   )r#   r$   rW   rX   tasktask_finish_datera   following_linksfollowing_linkfollowing_taskfollowing_gantt_taskr8   new_start_datedurations                 rF   r>   z.CmfRelationOption.sort_task_by_order_relationsf   sY   
 ?F 	55Dd??F~!!$g)>)z)z)z " | | 	F	  oty  o  oRVR[Ra  o  ox|  yK  y]  o  o  hm  o  o  	p  	p  	p-? 	F<( 277AUW[^s  vL  ^M  ANAKTSW@X@Z@V @V @V 8 W W
 . *	w *	wN+3N#1#?  ,,-A-U-U-W-WXXX
 %.!((:(: < B GaHHM+04III!1!7  v%+%7%L%LXWegt%u%uN-26LLL/>NSRS!'!3!H!HScSiltkt!u!u1JJ>osJttN!5!FFF4B 1(9= !$8$I$MMM'HHJJ  %%d%;;;rzQ$AA.BSBY`dlqtuluAvvvvU*	w *	wrG   c                 @   | j         }| j        }t                      }|j        r|d |j        D             z  }|j        rI|j        j        r|d |j        j        D             z  }|                    |j        j        j                   |                    |           d S )Nc                     h | ]
}|d          S r    .0ts     rF   	<setcomp>zLCmfRelationOption._check_additional_parent_task_relations.<locals>.<setcomp>   s    <q<q<qQtW<q<q<qrG   c                     h | ]
}|d          S rw   rx   ry   s     rF   r|   zLCmfRelationOption._check_additional_parent_task_relations.<locals>.<setcomp>   s4      AB  AB  ABQ4  AB  AB  ABrG   )
gantt_path)	r   r   rY   cache_branch_gantt_pathr0   rZ   r   r_   _check_additional_relations)rA   
add_parent	add_childadd_parent_gantt_paths       rF   r2   z9CmfRelationOption._check_additional_parent_task_relations   s    ]
L	 #- 	r$9<q<qjNp<q<q<q$q!! 	G%= B(=  AB  ABR\Rh  SA  AB  AB  AB  )B%!%%j&<&?&EFFF--9N-OOOOOrG   c                     |                      d          \  }t                      t                      fd | j        j        j                  S )NT)include_finish_finishc                     | v rdS | v rdS                      |                                 |                                | g           D ]\  }} |          }|r|c S                     |            dS NTF)rZ   r:   remove)nodeneighbor_resultdfs	stack_settask_out_linksvisiteds       rF   r   z4CmfRelationOption.has_start_finish_loop.<locals>.dfs   s    y  twuKKMM$-11$;; " "!X "!MMM" T"""5rG   )get_start_finish_graphsrY   r   op_gantt_task_idr_   )rA   r   r   r   r   r   s     @@@@rF   r/   z'CmfRelationOption.has_start_finish_loop   su     88t8TT%%EE		 	 	 	 	 	 	 	& s4=17888rG   returnc                     t           j                            g d          j        dfd	fd} || j        | j                  p || j        | j                  S )u   
        Проверяет, что связанные задачи не находятся друг у друга в родителях
        )r,   r   r   r   r   c                 N   |dk    rt          dd           t                      }ddgdd| gg}dd	g}t          j                            ||
          D ]}|j        }|j        rU|j        j        r*|j        j        D ]}|                    |d                    |                    |j        j	                   |                    |j	                   t                      }|D ])}	 |	|dz             }
|
r|
                    |
           *|
                    |           |S )Nd   ui   DEV: Защита от рекурсии: cmf_realtion_option.has_parent_child_relations: if r_count > 100Tr   r   r   out_link_idr   r   rR   r   rK   )r_count)r)   rY   r&   r	   slistr   r0   r   rZ   r   r   )r#   r   additional_parent_ids_filter_fieldsreladd_parent_taskr{   sub_additional_parent_idsr   additional_ids_add_additional_parent_idsadditonal_parent_type_ids              rF   r   zPCmfRelationOption.has_parent_child_relations.<locals>._add_additional_parent_ids   s   }}  F  NR  S  S  S  S$'EE! $T+CDg.G C.0G /55WW5UU > >"%+". N&2J ?!0!<!T ? ?A155ag>>>>)--o.I.LMMM%))/*<====(+%+ E E!;!;BRS!T!T!T! E-44^DDD!(()BCCC((rG   c                    t          |j        j        g          }|j        rZ|                    |j        j        j                   |j        j        r*|j        j        D ]}|                    |d                    t                      }|D ]$} |          }|r|                    |           %|                    |           | j        j        |v S )Nr   )rY   r   r_   r0   rZ   r   r   )childparentparent_task_idsr{   additional_parent_task_idsr   r   r   s          rF   _find_in_parentszFCmfRelationOption.has_parent_child_relations.<locals>._find_in_parents  s    !69?"344O! 5##F$6$9$?@@@%= 5#/G 5 5'++AdG4444),&% F F!;!;B!?!?! F.55nEEE""#=>>>8>_44rG   )r   )r&   CmfRelationTyper*   r   r   r   )rA   r   r   r   s     @@rF   r.   z,CmfRelationOption.has_parent_child_relations   s     $*#9#>#>FpFpFp#>#q#q#t 	) 	) 	) 	) 	) 	) 	)@	5 	5 	5 	5 	5&  dm<<m@P@PQUQ^`d`l@m@mmrG   c                     t                      t                      d fd | j        j        j        j                  S )Nc                 @   g }t           j                            dd| gdg          }|r&|j        r|                    |j        j                   dd| gg dg}t           j                            |dg          }|r!d	 |D             }|                    |           |S )
Nr   r   zparent_task.op_gantt_task_idrR   zout_link.op_gantt_task_id=)r   r   r   zin_link.op_gantt_task_idc                 &    g | ]}|j         j        S rx   )r   r   )rz   r   s     rF   
<listcomp>zXCmfRelationOption.has_additional_parent_loop.<locals>.get_parent_ids.<locals>.<listcomp>)  s    (n(n(n#)E(n(n(nrG   )	r&   r[   r*   r0   appendr   r	   r   extend)gantt_task_id
parent_idsrm   r   additional_parents_relationsr   s         rF   get_parent_idszDCmfRelationOption.has_additional_parent_loop.<locals>.get_parent_ids  s    J>&&/A4.Wa  aA&  B  BD E( E!!$"2"CDDD -c=AGGGG ,2+C+I+IQXb|a}+I+~+~(+ 9(n(nQm(n(n(n%!!"7888rG   c                     | v rdS | v rdS                      |                                 |             |           D ]} |          }|r|c S                     |            dS r   )rZ   r   )r   r   r   r   r   r   r   s      rF   r   z9CmfRelationOption.has_additional_parent_loop.<locals>.dfs.  s    y  twuKKMM$*N400 " "X "!MMM" T"""5rG   )rY   r   r5   r   r_   )rA   r   r   r   r   s    @@@@rF   r1   z,CmfRelationOption.has_additional_parent_loop  sl    %%EE		 	 	$	 	 	 	 	 	 	 	& s4=.17888rG   c                 N    t                                                      g dz   S )N)r+   zout_link.project_idzin_link.project_id)r3   rc   )rA   rE   s    rF   rc   z%CmfRelationOption.save_preload_fieldsC  s%    ww**,,/m/m/mmmrG   c                     |                      ddg           | j        r2| j        j        r&| j        j                            d| j                   | j        r4| j        j        r*| j        j                            d| j                   d S d S d S Nzout_link.projectzin_link.projectzPPP-TSK-LINK)objr-   r   r`   check_project_role_accessr   rA   s    rF   check_edit_permz!CmfRelationOption.check_edit_permF  s    ,.?@AAA= 	_T]2 	_M!;;NPTP];^^^< 	]DL0 	]L ::>t|:\\\\\	] 	] 	] 	]rG   c                     |                      ddg           | j        r2| j        j        r&| j        j                            d| j                   | j        r4| j        j        r*| j        j                            d| j                   d S d S d S r   r   r   s    rF   check_delete_permz#CmfRelationOption.check_delete_permN  s    ,.?@AAA= 	_T]2 	_M!;;NPTP];^^^< 	]DL0 	]L ::>t|:\\\\\	] 	] 	] 	]rG   r   c           	         |                      ddg           t          j        sd S | j        r| j        j        r| j        j        j        j        dk    rt          j        t          j        j        j        dgd| j        j        j        dgt          j	        | j        j        j        j        d}t          d|d	          ||d	         |d	         g
           | j        r| j        j        r| j        j        j        j        dk    rt          j        t          j        j        j        dgd| j        j        j        dgt          j	        | j        j        j        j        d}t          d|d	          ||d	         |d	         g
           d S d S d S d S )Nzout_link.parent.idzin_link.parent.id
CmfProjectproject_notifyr   in_tasks)initiatorSessionTabIdinitiatorCurrentPersonr$   initiatorActioninitiatorObjIdinitiatorObjChangedFieldsu   initiatorСomponentId	projectIdzproject_notify-r   )roomevent_persons	out_tasks)r-   r\   session_tab_idr   r   r_   
class_namecurrent_personr   component_idcmf_emit_eventr   )rA   initiator_actionevents      rF   r   z CmfRelationOption.project_notifyU  s    	.0CDEEE	 F= 	GT]1 	Gdm6J6P6[_k6k6k)*)9*+*:*=*C+,#+"&-"2"8.8\)*!]14:	 	E AU;-?AA5uU`Oarw  yD  sE  rF  G  G  G  G< 	GDL/ 	GDL4G4M4X\h4h4h)*)9*+*:*=*C+,#+"&,/"7.9])*!\039	 	E AU;-?AA5uU`Oarw  yD  sE  rF  G  G  G  G  G  G	G 	G 	G 	G4h4hrG   c                 <    t          j        j        | dg|R i | d S )Nupdatedr&   CmfEventdo_eventrA   rB   r%   s      rF   _do_event_savez CmfRelationOption._do_event_savev  s/     	 yB4BBB6BBBBBrG   c                 <    t          j        j        | dg|R i | d S )Ndeletedr   r   s      rF   _do_event_deletedz#CmfRelationOption._do_event_deleted{  s-     yB4BBB6BBBBBrG   Fc                    fd}t          t                    t          t                    g d}dg}|r|                    d           dd|gg}t          j                            ||          D ]n}|j        j                                     |j        j        |j	        f           |j        j                                     |j        j        |j	        f           o| r ||           S fS )Nc                 d   t          |           }t                      }t                      }t                      }|rq|                                }	|         ||<   |         ||<   |                    |           ||         ||         z   D ]\  }}||vr|                    |           |q||fS )N)r   rY   dictpopleftrZ   r   )
r   qdonefiltered_task_out_linksfiltered_task_in_linkscurelr   task_in_linksr   s
           rF   _filter_by_gantt_task_idzKCmfRelationOption.get_start_finish_graphs.<locals>._filter_by_gantt_task_id  s    }&&A55D&*ff#%)VV" %iikk/=c/B',.;C.@&s+4S9<RSV<WW % %EB~~  % +,BBBrG   )r   r   r8   r   r   r   r   rR   )
r   rb   r   r&   r	   r   r   r   r   r8   )	r   r   r   
rel_fields	rel_types
rel_filterr   r   r   s	          @@rF   r   z)CmfRelationOption.get_start_finish_graphs~  s7   	C 	C 	C 	C 	C 	C" %T**#D))
 
 

 ++	  	53444 "43

 +11J1WW 	s 	sC3<89@@#+B^`c`qArsss#+67>>@]_b_p?qrrrr 	;++M:::},,rG   )NNNr   )r   )NF)__name__
__module____qualname____doc__r4   rI   staticmethodcmf_deferred_jobr>   r2   r/   boolr.   r1   rc   r   r   r   r   r   r   __classcell__)rE   s   @rF   r	   r	      s       XXI I I I IV    " $PY{ef #HI I IGw Gw GwI I \GwRP P P9 9 969nD 9n 9n 9n 9nv*9 *9 *9Xn n n n n] ] ]] ] ]G G G GBC C C
C C C *- *- *- \*- *- *- *- *-rG   r	   N)cmf.includemodules.task.fieldsr   collectionsr   r   r   r	   rx   rG   rF   <module>r      s        3 3 3 3 3 3 6 6 6 6 6 6 6 6 6 6b- b- b- b- b-+= b- b- b- b- b-rG   