B
    f_                 @   s>   d dl mZ d dlT ddlmZ d dlZG dd dejZdS )    )fields)*   )cmf_approveNc                   s   e Zd ZdZejjddg Zedd Zedd Z	ed,ddZ
edd Zedd Zedd Zed-ddZedd Zedd Zdd Zed.ddZedd Zd/d d!Zed"d# Zed$d% Zd&d' Z fd(d)Zed*d+ Z  ZS )0
CmfApproveu   
        Модель для утверждения объектов в системе.
        Утверждает объекта его конкретную cmf_version
    add_approverZapprove_onec             C   s   g }t jjddd}xl|D ]d}|jdkr|jr|j|krt jj|j|jd|jj d|d|jj	 d|jj dd	 |
|j qW d S )
Nztask.doc_need_approve:defaultT)codeZcache_inmemorypersonu(   Необходимо утвердить u   Утвердите: <a href="z">z</a>)Zresponsibleparentnamelogic_prefix
logic_typetext)modelsZCmfLogicTypegetapprove_typeapproverCmfTaskZcreateobjr   Zhrefappend)clsapprovesZexisting_approversr   approve r   (./modules/settings/models/cmf_approve.py_create_tasks   s    

zCmfApprove._create_tasksc             C   s<   t jj|ddgd}x"|D ]}|jd|_|  qW d S )Nztask.doc_need_approve:defaultworkflow)r
   r   r   ZCLOSED)r   r   listr   Zget_default_statusstatussave)r   r   ZtasksZtaskr   r   r   _delete_tasks)   s    

zCmfApprove._delete_tasksr	   Nstandartc          	   C   s   dd|gdd|gdd|gdd|gdd|gdd|gdd|gg}t jj|d	gd
}	|	sjt j|||||||d}	|dkr|	jst jj|dd}
|
rd|
_|
jdd d|	_d|	_d |	_d|	_|	  |	S )Nr   z==r   obj_version
obj_statusapprove_groupr   approver_levelis_cur_approve)filterr   )r   r   r"   r#   r$   r   r%   fullT)r   r&   F)	only_dataopen )r   r   r   r&   r   r   
resolutionr   )r   r   r   r"   r#   r%   r   r$   r'   r   Zold_cur_approver   r   r   _create_or_update_approve4   s,    
 z$CmfApprove._create_or_update_approvec             C   sP   g }xF|j jD ]:}t|tjr*|| qx|j D ]}|| q6W qW |S )N)r   master_approvers
isinstancer   	CmfPersonr   
rg_membersload)r   r   Zresr   r	   r   r   r   _get_status_master_approversZ   s    z'CmfApprove._get_status_master_approversc             C   s  | ddddddddd	g	 g }| jd
|||jd}xn| |D ]`}t|tjrj| jd|||jd|d}n,x*|j D ]}| jd|||jd|d}qvW |	| q@W x|jj
D ]}| |||}qW t|tjs| | t|drx"dd |D D ]}|j	| qW |jdd d S )Nr
   projectzstatus.master_approverszstatus.approve_groupsz#status.approve_groups.min_approverszstatus.approve_groups.approversz&status.approve_groups.master_approversz*status.approve_groups.approvers.rg_membersz1status.approve_groups.master_approvers.rg_membersr(   )r   r   r"   r#   r	   grand_master)r   r   r"   r#   r%   r   approvers_forc             S   s"   g | ]}|j d kr|jr|jqS )r	   )r   r   ).0r   r   r   r   
<listcomp>   s    z/CmfApprove._create_approves.<locals>.<listcomp>T)r)   )load_fieldsr-   r   r3   r/   r   r0   Zdefault_membersr2   r   approve_groupscreate_approvegroup_approvesr   r   hasattrr6   r   )r   r   r"   created_approvesr   r   r	   app_grr   r   r   _create_approvesf   s@    



zCmfApprove._create_approvesc             C   s0   t jj||d}x|D ]}d|_|  qW d S )N)r$   r   closed)r   r   r   r   r   )r   r>   r   r   r   r   r   r   remove_approvegroup_approves   s    
z'CmfApprove.remove_approvegroup_approvesr   c       	      C   sB  g }| j d|||j|d}|jdkrf|j}|s2d}x2t|D ]&}| j d|||jd|d}|| q<W x>|d|jj|D ](}| j d|||j|d|d	}|| qzW x~|d
|jj|D ]h}| j d|||j|d|d	}|| x>|d
|jj|D ](}| j d|||j|d|d	}|| qW qW t	|t
js>| | |S )Nr$   )r   r   r"   r#   r$   custom   r	   r!   )r   r   r"   r#   r%   r$   	approvers)r   r   r"   r#   r$   r%   r   r.   master)r-   r   required_signsmin_approversranger   get_all_approversr4   valuer/   r   r   r   )	r   r>   r   r"   r=   r   Zmin_apprir   r   r   r   r;      s`    


z'CmfApprove.create_approvegroup_approvesc             O   s   | j ||f|| d S )N)r?   )r   r   r"   argskwargsr   r   r   start_approve_process   s    z CmfApprove.start_approve_processc             O   s   |  | d S )N)r    )r   r   rL   rM   r   r   r   cancel_approve_process   s    z!CmfApprove.cancel_approve_processc             C   s"   |  ddg | | j| j d S )Nr   z
obj.status)r9   calc_statusr   r"   )selfr   r   r   _calc_status   s    zCmfApprove._calc_statusc             C   sL   |  || tjj||ddgd}|j}|dkr8|  |dkrH|  dS )u   
        Рассчитывает агрегаты и, если надо, двигает статусы объекта по БП
        r(   r,   )r   r"   r   r   approvedrejectedN)calc_aggreg_resultr   r   r   r,   Z_approve_approvedZ_approve_rejected)r   r   r"   ZaggregZ
app_resultr   r   r   rP      s    zCmfApprove.calc_statusc          
   O   s(  |j ddddddddg |j js(d S tjj||j |d	d
dddgd}tjj||j |dd}dd |D }x&dd |D D ]}|j|_|  q|W d}	xn|j j	D ]b}
| 
|
|}tjj||j j|d|
d}|r||_|dkrd}	|  |dkrd|_|  d S qW |	rd|_nd|_|  d S )NrD   need_approver.   r:   zapprove_groups.approverszapprove_groups.master_approverszapprove_groups.min_approverszapprove_groups.required_signsr	   r%   r,   r$   r   )r   r#   r"   r   r   r(   )r   r#   r"   r   c             S   s.   g | ]&}|j d kr|jdk	r|jdkr|qS )r5   Nr(   )r%   r,   r   )r7   ar   r   r   r8     s    z1CmfApprove.calc_aggreg_result.<locals>.<listcomp>c             S   s$   g | ]}|j d ks|j dkr|qS )rT   rS   )r,   )r7   rW   r   r   r   r8     s    T)r   r#   r"   r   r$   rS   FrT   
in_approve)r   r9   rV   r   r   r   r   r,   r   r:   get_approve_group_statusrJ   )r   r   r"   rL   rM   r   Zaggreg_fullZfull_master_approver   Zall_approvedr$   Zapprove_group_statusZaggreg_groupr   r   r   rU      s8     
zCmfApprove.calc_aggreg_resultc          
   K   sf   |  ddddddddg | js4| jjd	kr4tj| _d
| _tj | _	|| _
|| _|   |   | S )u  
        Аппрувит текущего пользователя
        :params:
        approve_group - Аппрув группа, которой принадлежит аппрув. Один чел может аппрувить за разные группы.
        text - Комментарий пользователя при утверждении/отклонении
        r   z
obj.statuszobj.workflowzobj.approve_groupr%   r"   r   zapprove_group.required_signsrB   r@   )r9   r   r$   rF   gZcurrent_userr   datetimeZnowZapproved_atr,   r   r   rR   )rQ   r,   r   rM   r   r   r   _approve_one$  s    zCmfApprove._approve_onec             C   sL  |rddg}ndg}x0|D ]&}ddd|gdd|gddd	gd
ddgdd|j gdd|gdd|gg}tjj|d
ddddgd}|dkr|d|jj|}n&|dkr|d|jj|}n
| |}x&|D ]}	|	d
 |krd|	_ |	  qW g }
xB|D ]:}|dd |D kr| j	d	|||j |||d}	|

|	 qW t|tjs| |
 qW dS )u   
        Вызывается при изменении реквизитов аппрув-группы или мастер-аппруверов статуса
        Перезаполняет аппрувы
        r!   rE   r5   ZANDr$   z==r   r   r	   r   z!=Nr#   r%   r"   r,   r   )r'   r   rD   r.   r@   c             S   s   g | ]
}|j qS r   )r   )r7   Zapprr   r   r   r8   d  s    z.CmfApprove.update_approves.<locals>.<listcomp>)r   r   r"   r#   r$   r%   r   )r   r   r   r   rI   r4   rJ   r3   r   r-   r   r/   r   r   )r   r>   r   r"   Zapprover_levelsr%   ZfiltZexisting_approvesZcurrent_approvesr   r=   r   r   r   r   update_approves;  sF    





zCmfApprove.update_approvesc                s    fdd|D }xdd |D D ]}|j S W  fdd|D rDdS  fdd|D } jjdkr jdkrrd	}q jd
krt j}n j}t||krdS dS dS )u<  
        Получает статус аппрув-группы, исходя из списка собранных подписей
        :param app_gr:   Аппрувгруппа
        :param approves: Все подписи объекта:
        :rtype: str
        :return:
            approved - Утверждено (Все необходимые подписи собраны)
            rejected - Отклонено
            in_approve- В процессе утверждения
            None - Утверждение не требуется
        c                s$   g | ]}|j d kr|j kr|qS )rE   )r%   r$   )r7   rW   )r>   r   r   r8     s    z7CmfApprove.get_approve_group_status.<locals>.<listcomp>c             S   s.   g | ]&}|j d ks&|j dks&|j dkr|qS )rT   acceptedrS   )r,   )r7   rW   r   r   r   r8     s    c                s$   g | ]}|j  kr|jd kr|qS )rT   )r$   r,   )r7   rW   )r>   r   r   r8     s    rT   c                s0   g | ](}|j  kr|jd ks&|jdkr|jqS )r^   rS   )r$   r,   r   )r7   rW   )r>   r   r   r8     s    NrB   rC   ZfixedrS   rX   )r,   rG   rJ   rF   lenrD   )r   r>   r   Zmaster_approvesr   Zapproved_approversrG   r   )r>   r   rY   r  s     

z#CmfApprove.get_approve_group_statusc             C   sf   |  dddg | jdkrd S | js(d S | js:| jjs:d S d| jj }tjj	| j| j|||d d S )Nr   r   r   r	   u&   Требуется утвердить )r   r	   r   msgr   )
r9   r   r   Zis_newZ
is_changedr   r   r   Z	CmfNotifyZplace_notify)rQ   messager   r   r   _place_notify  s    
zCmfApprove._place_notifyc                s   |    t j||S )N)rb   superr   )rQ   rL   rM   )	__class__r   r   r     s    zCmfApprove.savec       
      K   s  t jj|d}|dg ||}t jj|d}g }|dd }|dkrt jj|d}t jf d||j	|j
d||dd	|d

|}	|	  ||	 nf|dkrt jj|d}xN|j D ]@}t jf d||j	|j
d||dd	|d

|}	|	  ||	 qW t|t js| | dS )u  
        Добавляет либо один аппрув, если пришла персона, либо аппрувы всех членов группы персон или еще там какого орг.юнита
        :param obj_id: Объект, который аппрувим:
        :param approver_id: Персона или группа персон\подразделение итп:
        :param approve_group_id:   Аппрувгруппа
        )idr   :r   r0   r	   r*   Nr!   )
r   r   r"   r#   r   r   r
   r,   r%   r$   CmfPersonGroup)r   ZCmfDocumentr   r9   Zget_in_approveZCmfApproveGroupsplitr0   r   Zdoc_versionr   r   r   rg   r1   Z
all_nestedr/   r   r   )
r   r   r   r$   r"   rM   Zdoc_histr=   Zappr_prefixr   r   r   r   r     sN    
zCmfApprove.add_approver)r	   NNNr!   NN)r   )r   )N)__name__
__module____qualname____doc__r   r   Zapi_methodsclassmethodr   r    r-   r3   r?   rA   r;   rN   rO   rR   rP   rU   r\   r]   rY   rb   r   r   __classcell__r   r   )rd   r   r      s>         -A+
7)r   )Zcmfr   Zcmf.includer   r[   r   r   r   r   r   <module>   s   