U
    Af_                     @   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}|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d S )
N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   s8   t jj|ddgd}|D ]}|jd|_|  qd S )Nr   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   ==r   obj_version
obj_statusapprove_groupr   approver_levelis_cur_approvefilterr   )r   r   r$   r%   r&   r   r'   fullT)r   r(   FZ	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   s4    
   	z$CmfApprove._create_or_update_approvec                 C   sH   g }|j jD ]6}t|tjr(|| q|j D ]}|| q2q|S N)r   master_approvers
isinstancer   	CmfPersonr   
rg_membersload)r   r   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}| |D ]\}t|tjrh| jd|||jd|d}n(|j D ]}| jd|||jd|d}qr|	| q>|jj
D ]}| |||}qt|tjs| | t|drdd |D D ]}|j	| q|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>Tr,   )load_fieldsr0   r   r8   r3   r   r4   Zdefault_membersr6   r   approve_groupscreate_approvegroup_approvesr   r   hasattrr;   r    )r   r   r$   created_approvesr   r   r
   app_grr   r   r   _create_approvesf   sL      
zCmfApprove._create_approvesc                 C   s,   t jj||d}|D ]}d|_|  qd S )N)r&   r   closed)r   r   r   r   r    )r   rC   r   r   r   r   r   r   remove_approvegroup_approves   s    z'CmfApprove.remove_approvegroup_approvesr   c           	      C   s2  g }| j d|||j|d}|jdkrb|j}|s2d}t|D ]&}| j d|||jd|d}|| q:|d|jj|D ](}| j d|||j|d|d	}|| qt|d
|jj|D ]d}| j d|||j|d|d	}|| |d
|jj|D ](}| j d|||j|d|d	}|| qqt	|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   r2   master)r0   r   required_signsmin_approversranger   get_all_approversr9   valuer3   r   r   r   )	r   rC   r   r$   rB   r   Zmin_apprir   r   r   r   r@      sj    


z'CmfApprove.create_approvegroup_approvesc                 O   s   | j ||f|| d S r1   )rD   )r   r   r$   argskwargsr   r   r   start_approve_process   s    z CmfApprove.start_approve_processc                 O   s   |  | d S r1   )r!   )r   r   rR   rS   r   r   r   cancel_approve_process   s    z!CmfApprove.cancel_approve_processc                 C   s"   |  ddg | | j| j d S )Nr   
obj.status)r>   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   rW      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 }dd |D D ]}|j|_|  qzd}	|j j	D ]d}
| 
|
|}tjj||j j|d|
d}|r||_|dkrd}	|  |dkrd|_|   d S q|	rd|_nd|_|  d S )NrI   need_approver2   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 )r:   Nr+   )r'   r/   r   r<   ar   r   r   r=     s
     
 
 
 z1CmfApprove.calc_aggreg_result.<locals>.<listcomp>c                 S   s$   g | ]}|j d ks|j dkr|qS )r[   rZ   r/   r^   r   r   r   r=     s     
 
 T)r   r%   r$   r   r&   rZ   Fr[   
in_approve)r   r>   r]   r   r   r   r   r/   r    r?   get_approve_group_statusrP   )r   r   r$   rR   rS   r   Zaggreg_fullZfull_master_approver   Zall_approvedr&   Zapprove_group_statusZaggreg_groupr   r   r   r\      sB       
 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   rV   zobj.workflowzobj.approve_groupr'   r$   r   zapprove_group.required_signsrG   rE   )r>   r   r&   rL   gZcurrent_userr   datetimeZnowZapproved_atr/   r   r    rY   )rX   r/   r   rS   r   r   r   _approve_one$  s    zCmfApprove._approve_onec                 C   s>  |rddg}ndg}|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
| |}|D ]}	|	d
 |krd|	_ |	  qg }
|D ]:}|dd |D kr| j	d	|||j |||d}	|

|	 qt|tjs| |
 qdS )u   
        Вызывается при изменении реквизитов аппрув-группы или мастер-аппруверов статуса
        Перезаполняет аппрувы
        r"   rK   r:   ZANDr&   r#   r   r   r
   r   z!=Nr%   r'   r$   r/   r   r)   rI   r2   rE   c                 S   s   g | ]
}|j qS r   )r   )r<   Zapprr   r   r   r=   d  s     z.CmfApprove.update_approves.<locals>.<listcomp>rJ   )r   r   r   r   rO   r9   rP   r8   r    r0   r   r3   r   r   )r   rC   r   r$   Zapprover_levelsr'   ZfiltZexisting_approvesZcurrent_approvesr   rB   r   r   r   r   update_approves;  sL    





zCmfApprove.update_approvesc                    s    fdd|D }dd |D D ]}|j   S  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 )rK   )r'   r&   r^   rC   r   r   r=     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 )r[   acceptedrZ   r`   r^   r   r   r   r=     s
     
 
 
 c                    s$   g | ]}|j  kr|jd kr|qS )r[   )r&   r/   r^   rg   r   r   r=     s     
 
 r[   c                    s0   g | ](}|j  kr|jd ks&|jdkr|jqS )rh   rZ   )r&   r/   r   r^   rg   r   r   r=     s
     
 
 
 NrG   rH   ZfixedrZ   ra   )r/   rM   rP   rL   lenrI   )r   rC   r   Zmaster_approvesr   Zapproved_approversrM   r   rg   r   rb   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   )
r>   r   r   Zis_newZ
is_changedr   r   r   Z	CmfNotifyZplace_notify)rX   messager   r   r   _place_notify  s    
zCmfApprove._place_notifyc                    s   |    t j||S r1   )rl   superr    )rX   rR   rS   	__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

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

|}	|	  ||	 qt|t js| | dS )u  
        Добавляет либо один аппрув, если пришла персона, либо аппрувы всех членов группы персон или еще там какого орг.юнита
        :param obj_id: Объект, который аппрувим:
        :param approver_id: Персона или группа персон\подразделение итп:
        :param approve_group_id:   Аппрувгруппа
        )idr   :r   r4   r
   r-   Nr"   )
r   r   r$   r%   r   r   r   r/   r'   r&   CmfPersonGroup)r   ZCmfDocumentr   r>   Zget_in_approveZCmfApproveGroupsplitr4   r   Zdoc_versionr   r    r   rr   r5   Z
all_nestedr3   r   r   )
r   r   r   r&   r$   rS   Zdoc_histrB   Zappr_prefixr   r   r   r   r     sV    


zCmfApprove.add_approver)r
   NNNr"   NN)r   )r   )N)__name__
__module____qualname____doc__r   r   Zapi_methodsclassmethodr   r!   r0   r8   rD   rF   r@   rT   rU   rY   rW   r\   re   rf   rb   rl   r    r   __classcell__r   r   rn   r   r      sX   	


       %

,
A


*

6
(r   )Zcmfr   Zcmf.includer   rd   r   r   r   r   r   <module>   s   