
    ?RhK                     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           | j
        j        dk    r%|                                 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k    rb| j        s| j        j        rO| j        j        j        r>| j        j        j        r-t7          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   Невозможно связать суммарную задачу с одной из ее подзадач.r   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   u   Невозможно связать задачи связью Дополнительный родитель/Дополнительная дочерняя задача, так как они связаны связью ОО/ОН.
after_save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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.pyr3   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!&*???DD^D^D`D`?  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"&;;;;PTPbPm;}*; 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,   r2   rG   r*   r+   r   r4   r5   r=   obj_after_delete_hook)r?   r@   r$   rB   rC   s       rD   rG   zCmfRelationOption.deleteR   s    '11$-PPP/*+++eggnd-f--"&@@@'    L&QQSSS'11$,OOO44T:::
rE   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 t          j                            g d	d
d|ggg d          }|D ]5}|j        }|j
        }	|	                    |	                                           |	j        r|dk    r|dk    sLt%          |j        j        pd          }
||	j        k    r|j        }|
r-|j        j        }t          j                            |||
          }|	                    |d          }||	_        |	                                }|r|	                    d           |dz  rt9                       t          j                            |j        j        ||dz              7d S )Nr   r   )r4   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   r7   r   r!   T)return_correct_date)from_sort_order
   rI   )pathdepth)setaddr%   CmfTaskgetgdebugnamevaluer+   r4   r:   r	   listr   r,   save_preload_fields	is_manualintr7   r9   projectcalendarCmfCalendarget_date_by_durationcheck_correct_start_date _get_task_blocking_back_movementr3   
cmf_commitr<   r   )r"   r#   rU   rV   tasktask_finish_datefollowing_linksfollowing_linkfollowing_taskfollowing_gantt_taskr7   new_start_daterd   blocking_tasks                 rD   r<   z.CmfRelationOption.sort_task_by_order_relationsc   s   
 ?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7@s@s@sAKTSW@X@Z?t?t?t 8 v v . 	{ 	{N+3N#1#?  ,,-A-U-U-W-WXXX
 %.!((:(: < B GaHHM#7#HHH!1!7  v#|4H%+%7%L%LXWegt%u%uN!5!N!N~sw!N!x!x8F$5 4 U U W W  $))$)???2: !LLL(EEnFWF]dhpuxypyEzzz;	{ 	{rE   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     rD   	<setcomp>zLCmfRelationOption._check_additional_parent_task_relations.<locals>.<setcomp>   s    <q<q<qQtW<q<q<qrE   c                     h | ]
}|d          S rt   ru   rv   s     rD   ry   zLCmfRelationOption._check_additional_parent_task_relations.<locals>.<setcomp>   s4      AB  AB  ABQ4  AB  AB  ABrE   )
gantt_path)	r   r   rW   cache_branch_gantt_pathr/   rX   r   r^   _check_additional_relations)r?   
add_parent	add_childadd_parent_gantt_paths       rD   r1   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OrE   c                     t           j                                        \  }t                      t                      fd | j        j        j                  S )Nc                     | v rdS | v rdS                      |                                 |                                | g           D ]\  }} |          }|r|c S                     |            dS NTF)rX   rZ   remove)nodeneighbor_resultdfs	stack_settask_out_linksvisiteds       rD   r   z4CmfRelationOption.has_start_finish_loop.<locals>.dfs   s    y  twuKKMM$-11$;; " "!X "!MMM" T"""5rE   )r%   r	   get_start_finish_graphsrW   r   op_gantt_task_idr^   )r?   r   r   r   r   r   s     @@@@rD   r.   z'CmfRelationOption.has_start_finish_loop   ss    "4LLNN%%EE		 	 	 	 	 	 	 	& s4=17888rE   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   rP   r   rI   )r_count)r(   rW   r%   r	   slistr   r/   r|   rX   r   r   )r"   r   additional_parent_ids_filter_fieldsreladd_parent_taskrx   sub_additional_parent_idsr   additional_ids_add_additional_parent_idsadditonal_parent_type_ids              rD   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((rE   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   )rW   r   r^   r/   rX   r|   r   )childparentparent_task_idsrx   additional_parent_task_idsr   r   r   s          rD   _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4rE   )r   )r%   CmfRelationTyper)   r   r   r   )r?   r   r   r   s     @@rD   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mrE   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_idrP   zout_link.op_gantt_task_id=)r   r   r   zin_link.op_gantt_task_idc                 &    g | ]}|j         j        S ru   )r   r   )rw   r   s     rD   
<listcomp>zXCmfRelationOption.has_additional_parent_loop.<locals>.get_parent_ids.<locals>.<listcomp>  s    (n(n(n#)E(n(n(nrE   )	r%   rY   r)   r/   appendr   r	   r   extend)gantt_task_id
parent_idsrj   r   additional_parents_relationsr   s         rD   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rE   c                     | v rdS | v rdS                      |                                 |             |           D ]} |          }|r|c S                     |            dS r   )rX   r   )r   r   r   r   r   r   r   s      rD   r   z9CmfRelationOption.has_additional_parent_loop.<locals>.dfs  s    y  twuKKMM$*N400 " "X "!MMM" T"""5rE   )rW   r   r4   r   r^   )r?   r   r   r   r   s    @@@@rD   r0   z,CmfRelationOption.has_additional_parent_loop  sl    %%EE		 	 	$	 	 	 	 	 	 	 	& s4=.17888rE   c                 N    t                                                      g dz   S )N)r*   zout_link.project_idzin_link.project_id)r2   r`   )r?   rC   s    rD   r`   z%CmfRelationOption.save_preload_fields1  s%    ww**,,/m/m/mmmrE   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   rc   check_project_role_accessr   r?   s    rD   check_edit_permz!CmfRelationOption.check_edit_perm4  s    ,.?@AAA= 	_T]2 	_M!;;NPTP];^^^< 	]DL0 	]L ::>t|:\\\\\	] 	] 	] 	]rE   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    rD   check_delete_permz#CmfRelationOption.check_delete_perm<  s    ,.?@AAA= 	_T]2 	_M!;;NPTP];^^^< 	]DL0 	]L ::>t|:\\\\\	] 	] 	] 	]rE   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   )r?   initiator_actionevents      rD   r   z CmfRelationOption.project_notifyC  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4h4hrE   c                 <    t          j        j        | dg|R i | d S )Nupdatedr%   CmfEventdo_eventr?   r@   r$   s      rD   _do_event_savez CmfRelationOption._do_event_saved  s/     	 yB4BBB6BBBBBrE   c                 <    t          j        j        | dg|R i | d S )Ndeletedr   r   s      rD   _do_event_deletedz#CmfRelationOption._do_event_deletedi  s-     yB4BBB6BBBBBrE   c                    fd}t          t                    t          t                    g d}dddg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   rW   dictpopleftrX   r   )
r   qdonefiltered_task_out_linksfiltered_task_in_linkscurelr   task_in_linksr   s
           rD   _filter_by_gantt_task_idzKCmfRelationOption.get_start_finish_graphs.<locals>._filter_by_gantt_task_ido  s    }&&A55D&*ff#%)VV" %iikk/=c/B',.;C.@&s+4S9<RSV<WW % %EB~~  % +,BBBrE   )r   r   r7   r   r   r   rP   )
r   r_   r%   r	   r   r   r   r   r   r7   )r   r   
rel_fields
rel_filterr   r   r   s        @@rD   r   z)CmfRelationOption.get_start_finish_graphsl  s   	C 	C 	C 	C 	C 	C" %T**#D))
 
 

 "4*?)@A

 +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:::},,rE   )NNNr   )r   r   )__name__
__module____qualname____doc__r3   rG   staticmethodcmf_deferred_jobr<   r1   r.   boolr-   r0   r`   r   r   r   r   r   r   __classcell__)rC   s   @rD   r	   r	      s       XXF F F F FP    " $PY{ef #HI I I8{ 8{ 8{I I \8{t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 %- %- %- \%- %- %- %- %-rE   r	   N)cmf.includemodules.task.fieldsr   collectionsr   r   r   r	   ru   rE   rD   <module>r      s        3 3 3 3 3 3 6 6 6 6 6 6 6 6 6 6K- K- K- K- K-+= K- K- K- K- K-rE   