U
    bh/|                     @   sB   d dl T d dlZd dlmZ d dlmZ G dd dejjj	Z	dS )    )*N)	CmfEntity)CmfActiveEntityc                       sT  e Zd ZdZejjjjddddg Ze	d=dd	Z
d>d
dZdd Zd?ddZ fddZdd Zdd Zdd Zedd Zdd Z fddZ fdd Zd!d" Zd#d$ Zd%d& Zd@d'd(Zeed)dd*d+d, ZdA fd-d.	Zd/d0 ZdBd1d2Z dCd4d5Z!eeddd6d7d8 Z"eeddd6d9d: Z#eeddd6dDd;d<Z$  Z%S )ECmfWorkflowTstatus_listget_default_statusget_related_projects_inforeplaceNFc                 K   s  |s|st ddd |s dg}nd|kr2|d |s|dd|g}|rL||g}tjjf ||d|}	|rx|	jdd	 d
 |	S tj|ddgd}
tjj	dd|
j
jgdddddgdd}g }|stjjf dd|gdddgg|dd|}t|}|jD ]}|r|jsq|jrN|
jjjdd |jD krN|jrN|j|krN||j q|jjsr|
jjjdd |jD kr||
r|jsq||j qt|}|jdd	 d
 |S )Nz6DEV: FATAL get_status_list if not obj and not workflowTabortordernoworkflow==filterfieldsc                 S   s
   | j dkS Nclosedcodes r   ./common/models/cmf_workflow.py<lambda>!       z-CmfWorkflow.get_status_list.<locals>.<lambda>keystatusr   id=transztrans.status_to.ordernoztrans.status_fromztrans.trans_sdesk_portal_allowztrans.restrict_manual_transr   r   cache_inmemoryallow_empty_transitionc                 S   s   g | ]}|j jqS r   r    value.0tr   r   r   
<listcomp>A   s     z/CmfWorkflow.get_status_list.<locals>.<listcomp>c                 S   s   g | ]}|j jqS r   r&   r(   r   r   r   r+   E   s     c                 S   s   | j jS N)r   r'   r   r   r   r   r   K   r   )	cmf_alertappendmodels	CmfStatuslistsortZcmfutilZget_obj_by_idr   getr   r    setr"   trans_sdesk_portal_allowZrestrict_manual_transr   r'   status_from	status_toremoveZis_nulltrans_filter_okadd)clsZobj_idZworkflow_idr   closed_lastr6   r   kwargs
get_filterresobjr   Zvalid_statusesr"   r   r   r   get_status_list   sd    


8$
zCmfWorkflow.get_status_listc                 K   s`   dd| g}|r||g}|pg }d|kr0| d tjjf ||d|}|r\|jdd d |S )Nr   r   need_approve)r   r   c                 S   s
   | j dkS r   r   r   r   r   r   r   Z   r   z)CmfWorkflow.status_list.<locals>.<lambda>r   )r/   r0   r1   r2   r3   )selfr   r=   r   r>   r?   r@   r   r   r   r   N   s    

zCmfWorkflow.status_listc                 C   s   t jjd| dddgd}|jS )uN   Получает стартовый статус бизнес-процессаTr8   zstatus_to.need_approve)r$   r   is_create_transitionr   )r0   CmfTransr4   r8   )rD   r"   r   r   r   get_create_status^   s    zCmfWorkflow.get_create_statusOPENc              	      s   dg}d }|r$| j dd|g|d}np rN| j |dd}|jd fddd	 nF|d
krzdg}| j ddd
gdddgg|d}|s| j dd|g|dd}|r|d S |rtd|  d| d| d  d S )Nr   r   r   )r   order_byT)rI   r=   c                    s>   | j  j k| j jk| j jk| j jk jdko:| jdkfS )NZ	IN_REVIEWCLOSED)r    r   namestatus_typer   r-   r   r   r   q   s    



z0CmfWorkflow.get_default_status.<locals>.<lambda>)reverser   rJ   z-ordernorL   r   )r   rI   r=   r   u+   Отсутствует статус для z status_type=z, status_code=z	, status=)r   r3   ZCmfError)rD   rL   Zstatus_coder   Zraise_errorrI   r@   r   r-   r   r   d   sB    
 zCmfWorkflow.get_default_statusc                    s   t   dg S )Nr   )supersave_preload_fieldsrD   	__class__r   r   rO      s    zCmfWorkflow.save_preload_fieldsc                 C   sD   t jj| dd d}|s@| jdd}t jd| d |ddd}|  d S )NT)r   rE   r7   rH   )rL   u   Создание)rK   r   r7   r8   rE   system)r0   rF   r4   r   save)rD   r"   r8   r   r   r   create_create_trans   s    zCmfWorkflow.create_create_transc                    s  | j ddg i  | j jD ]v}|ddg | }d|_|j|_| |_|  | |< |jD ]0}|dddg | }d|_||_	|  q`q| j j
D ]"}|ddg | }d|_| |_ fd	d
|jD |_|jjr |j |_|  |dddg |jD ]6}|ddg | }d|_| |_||_|  q|jD ]6}	|	ddg |	 }
d|
_| |
_||
_|
  qJ|jD ]6}|ddg | }d|_| |_||_|  qq|   d S )Nstatusesr"   z**approve_groupsF	approversmaster_approversr7   c                    s   g | ]} | qS r   r   )r)   Z_stZstatus_mappingr   r   r+      s     zACmfWorkflow.scaffold_statuses_and_transitions.<locals>.<listcomp>trans_filterstrans_validatorstrans_actionsZwz_value_obj)templateload_fieldsrV   ZclonerS   r   r   rT   rW   parentr"   r7   r8   Zis_not_nullr[   
transitionr\   r]   rU   )rD   stZst_newZ
approve_grZapprove_gr_newr"   Z	trans_newr   Z
filter_newZ	validatorZvalidator_newactionZ
action_newr   rZ   r   !scaffold_statuses_and_transitions   sb    



z-CmfWorkflow.scaffold_statuses_and_transitionsc                 C   sR   | j sN| jjsF| jjsF| jjsF| jjsF| jjsF| jjsF| jjsF| j	jrNt
d dS )u   
        Оповещаем пользователя, если выбранные им галочки не будут активированы
        u   Для работы выбранных опций необходимо активировать "Переопределять опции Simple Logic Проекта". Иначе будут применяться настройки ПроектаN)Zenable_sl_controlZsl_deadline_shift
is_changedZsl_only_owner_approveZsl_deny_no_approveZ)sl_allow_executor_change_nofatal_deadlineZsl_task_need_approveZsl_readonly_closed_taskZsl_task_only_owner_closeZ.sl_deny_closing_task_before_closing_checklistsr.   rP   r   r   r   sl_consistent_warning   s"    z!CmfWorkflow.sl_consistent_warningc                 C   s   t tjj| dddS )uP   Возвращает есть ли на данном БП утверждениеT)r   rC   r$   )boolr0   r1   r4   rP   r   r   r   rC      s    zCmfWorkflow.need_approvec                 C   s(   | j ddg | j j| _| j j| _d S )Npublish_approved_onlypublish_by_owner_only)r^   r_   rh   ri   rP   r   r   r   scaffold_flags   s    
zCmfWorkflow.scaffold_flagsc                    sv   | j r| jstddd | jjr<tj  tj	s<tddd | 
  | j rR|   | j }t j|| |rr|   d S )NuB   Выберите шаблон для Бизнес-процессаTr
   u   Использование "Действий после сохранения объекта" недоступно в Вашей версии, обратитесь в Техническую поддержку.)is_newr^   r.   Zsave_eval_codere   r0   ZCmfAccessListZcheck_admin_modeZconfigZBZPYTHON_ENABLEDrf   rj   rN   rT   rd   rD   argsr>   rk   rQ   r   r   rT      s    
zCmfWorkflow.savec                    s2   | j r|   | j }t j|| |r.|   d S r,   )rk   rj   rN   _save_importrd   rl   rQ   r   r   rn     s    zCmfWorkflow._save_importc                 C   s   t jj| dgdd}|S )Ntarget_workflowT)ro   r   r$   )r0   CmfSchemeWfRuler2   )rD   Zrulesr   r   r   _get_related_rules  s    zCmfWorkflow._get_related_rulesc                    sR   ddddddddg}d	d
d   gg}| fdd|D 7 }tjj||dd}|S )Ndefault_list_workflowdefault_epic_workflowdefault_subproject_workflowdefault_release_workflowdefault_sprint_workflowdefault_document_workflowdefault_task_workflowdefault_subtask_workflowORscheme_wf_rulesINc                    s   g | ]}|d  gqS r   r   r)   fieldrP   r   r   r+     s     z4CmfWorkflow._get_related_schemes.<locals>.<listcomp>Tr#   )rq   r0   CmfSchemeWfr2   )rD   Zscheme_fieldsfilter_schemeZschemesr   rP   r   _get_related_schemes  s    z CmfWorkflow._get_related_schemesc                    sn  |   }tjjddd|gdd| ggd}ddd  fd	d
|D }tjjddd| gdd| ggdgd}|D ]6}|jrl||jj   ||jj d  d7  < qltj	jddd| gdd| ggdgd}|D ]6}|jr||jj   ||jj d  d7  < qi }|
 D ]H\}	}
|
 kr0|
||	jj< n&tj	j|	dtjj|	dd||	jj< q|rjt|S d S )Nrz   Z	scheme_wfr|   r   r   r   r   )tasksdocsc                    s   i | ]}|   qS r   )copy)r)   projectZdefault_scorer   r   
<dictcomp>)  s      z9CmfWorkflow.get_related_projects_info.<locals>.<dictcomp>rx   r   r   r      r   )r   )r   r0   Z
CmfProjectr2   CmfDocumentr   
setdefaultr'   r   CmfTaskitemsrK   countZjsondumps)rD   Zrelated_schemesZrelated_projectsZprojects_dictZrelated_docsdocZrelated_taskstaskZres_dictr   Z
count_dictr   r   r   r   $  s@    

z%CmfWorkflow.get_related_projects_infoc              	   K   sh   t jjdddddggdd| jjgdd	d
| jj d
ggd}|rLtddd tt j	j| jj|gd d S )NZANDr   r|   openZin_progressrK   r   Zparams_jsonZILIKE%r   uc   Работа по замене данного бизнес-процесса уже запущенаTr
   )rm   )
r0   ZCmfDeferredJobr   replace_workflowrK   r    r'   r.   Zschedule_deferred_jobr   )rD   new_workflow_id_kwargsZreplace_task_existsr   r   r   r	   G  s    zCmfWorkflow.replaceu(   Смена бизнес-процесса)descriptionZshow_bg_progressbarc                    s
  t jj| d t jj|d}t jj dgd}|D ]&}|j kr2||_|jdd t  q2dddd	d
dddg}ddd|gg}| fdd|D 7 }t jj||d}	|	D ]:}
|D ]}t	|
| krt
|
|| q|
jdd t  qddg}t D ]}|jdkrq|jdg fdd|D  |ddgd}|s4q|D ]:}|D ]"}t	|| kr@t
||| q@|jdd q8t  qqt D ]|}|jdkrqd|jkr|jdd gdgddgd}|sΐq|D ]$}|j kr||_|jdd qt  qqd S )N)r    ro   )ro   r   F)notifyrr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   c                    s   g | ]}|d  gqS r}   r   r~   Zold_workflowr   r   r+   i  s     z0CmfWorkflow.replace_workflow.<locals>.<listcomp>r   r   )rp   r   c                    s   g | ]}|d  gqS r}   r   r~   r   r   r   r+   z  s     r      )r   r   slice)r1   ZCmfTransActionZCmfTransFilterZCmfTransValidrF   default_workflowr   )r0   r   r4   rp   r2   ro   rT   Z
cmf_commitr   getattrsetattrr   iter_subclasses
class_namer   r   r   )Zold_workflow_idr   rm   r>   Znew_workflowZwf_rulesruleZwf_scheme_fieldsr   Z
wf_schemesschemer   Zactive_entity_fieldsmodelZobj_listrA   r   r   r   r   P  sv    

zCmfWorkflow.replace_workflowc                    st  d}g }t  D ]d}ddd| gdd| gg}t|drD|dd| g ||j|d7 }|r|s|jdd| gddgd	}q|r|d
 td| ddd tjj	| ||dD ]}|j
f |dd| qtjj	| ||dD ]}	|	j
f d|i| q|rXtjj	ddd| gdd| ggddg|dD ]6}
|
j| kr6d |
_|
j| krHd |
_|
jdd q t j
f ||d| d S )Nr   rz   r   r!   rx   ry   r   
   )r   r   z...u   Невозможно удалить используемый бизнес процесс. Данный бизнес процесс используется в u    объектахTr
   )r   include_deletedinclude_system)TEXKOM_db_deleteforce)ro   r   r   r   r   )r   r   r   Z	only_data)r   r   hasattrr/   r   Zslistr.   r0   r1   r2   deleterp   r   rx   ry   rT   rN   )rD   r   r   r>   Z	ref_countZ	top_usager   Z_filterr   r   r   rQ   r   r   r     s@    


 
zCmfWorkflow.deletec           	      C   s   |sdS g }|j rH|jsHdddgdd| gg}tjjd|d}|| n|sPdS |j rj|  }||krj|}tjjddd|jggd	d
|ggdD ] }|	|r|| |  S qtjjddd
dgd	d
|gdddggdD ] }|	|r|| |  S q|S )u  
        Может возвращать 2 перехода в случае, когда в дамми-объекте меняем статус.
        Тогда надо отрабатывать и транзишн create-перехода, и вычисленный транзишн на введенный пользователем статус
        https://bcrm.carbonsoft.ru/project/Document/DOC-016537#spec-perehod-pri-sozdanii-ob-ekta
        NrE   r   Tr   )r$   r   r7   r|   r8   r!   !=)
rk   Zis_templater0   rF   r4   r/   rG   r2   r    r:   )	rD   rA   r7   r8   r@   r   r"   Zcreate_statusZpossible_transitionr   r   r   calc_transition  s:    





zCmfWorkflow.calc_transitionc              	   C   s   d}t |dr|jrd S | |||}|sh|j  |jsdtd|j d|j d|j d| dd d S |D ]}|| ||	|O }ql|S )	NFis_dummyuA   Нет доступного перехода из статуса u    в статус u"    у Бизнес-процесса u    для объекта Tr
   )
r   r   r   r%   loadr.   rK   r   Ztrans_validator_okZtrans_run_actions)rD   rA   r7   r8   Zis_task_transition_runZhas_changesZtransitionsra   r   r   r   run_transition  s    
"
zCmfWorkflow.run_transitionr   c                 C   s   t jj|||d d S )N)obj_version)r0   
CmfApproveZupdate_approves)rD   rA   approve_groupr   r   r   r   recalc_approvegroup_approves  s    z(CmfWorkflow.recalc_approvegroup_approves)Z	only_onceZ
system_jobc                 C   s   dd| gdddgg}t jj|ddgdD ] }t j|| t j|d q(t jj|ddd	gdD ]$}t j|| t j||jj q`d S )
Nr   r   status.need_approveTr   r   r   r    cur_workflow_version.doc_version)	r0   r   r2   r   remove_approvegroup_approvescalc_statusr   cur_workflow_versiondoc_version)wfr   r   r   r   r   r   r   r   	  s    

z(CmfWorkflow.remove_approvegroup_approvesc                 C   s   t jj|dddgd}dd| gdddgg}t jj|d	d
gdD ] }t j|| t j|d q>t jj|d	d
ddgdD ]*}t j|||j	j
 t j||j	j
 qxd S )NrX   rY   Zmin_approversr   r   r   r   Tr   r   r   r   r   r   )r0   CmfApproveGroupr4   r   r2   r   Zcreate_approvegroup_approvesr   r   r   r   )wf_idapprove_group_idr   r   r   r   r   r   r   add_approvegroup_approves  s    


z%CmfWorkflow.add_approvegroup_approvesc              	   C   s  t j| }t jj|ddgd}dd|gdddgg}dd	d
ddddddg	}t jj||dD ]\}|rt jj|d|dgd}	|	d dksZ|	d dkrqZ||||jj	 t j
||jj	 qZt jj||dD ]V}
|rt jj|
d|dgd}	|	d dks|	d dkrq||
| t j
|
d q|s0|s0dS dddgdd|gdddgdddgdddgd dd!gg}t jj|ddd"gd}|sdS t|t| }t|t| }t }|D ]F}|r|jjj|kr|  td#|jj  ||jj q|r~t jjd$d%t|gd&}|D ]d}t|t jrB|j| |jdd' |D ]2}t jj||||jdd(}td)|jj  qFqdS )*uj  
        Перезаполняет аппрувы задач/документов на утверждении при изменении состава/свойств апрувгрупп или мастераппруверов статуса
        Если approve_group==None => поменялся статус. Иначе - аппрувгруппа
        rX   rY   r   r   r   r   Tr   zstatus.master_approverszstatus.approve_groupsz"status.approve_groups.approve_typezstatus.approve_groups.approversz&status.approve_groups.master_approversr   r   r   r   r   Z
resolution)rA   approve_typer   r   ZapprovedZrejectedr   Nr   r!   Zpersonapproverr   r   rA   zobj.cache_status_typerJ   z
obj.statusu   Удалили аппрув: r    r|   r   r   )rA   r   r   Z
obj_statusr   u(   Создали новый аппрув: )r0   r   r4   r   r   r2   r   r   r   r   r   r   r5   r   r    r'   r   gdebugr;   rA   Z	CmfPerson
isinstanceZapprovers_forextendrT   Z_create_or_update_approver   )r   r   Zapprovers_old_idsZapprovers_new_idsr   r   r   r   r   Zaggreg_groupr   Zapprove_filterZapprovesZadd_approversZdelete_approversZobj_idsZapproverA   Zadd_approverZnew_approver   r   r   recalc_all_approves-  sx        	zCmfWorkflow.recalc_all_approves)NNNFFN)NFN)rH   NNT)N)FF)F)r   )NNN)&__name__
__module____qualname__Z	api_allowcommonr   cmf_workflowr   Zapi_methodsclassmethodrB   r   rG   r   rO   rU   rd   rf   propertyrC   rj   rT   rn   rq   r   r   r	   staticmethodZcmf_deferred_jobr   r   r   r   r   r   r   r   __classcell__r   r   rQ   r   r      sV   
  =

.7
#
	
D$/




r   )
Zcmf.includeZcommon.fields.cmf_workflowr   Z
cmf.modelsr   Zcommon.models.cmf_active_entityr   r   r   r   r   r   r   r   <module>   s   