U
    ܌f<O                     @   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dd Zdd Zdd Zd$ddZedd Zdd Z fdd Zed!d" Z  ZS )%
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	}	|	sft j|||||||d
}	d|	_d |	_d|	_|	  |	S )Nr   z==r   obj_version
obj_statusapprove_groupr   approver_level)filter)r   r   r#   r$   r%   r   r&   open )r   r   r   r   
resolutionr   r    )
r   r   r   r#   r$   r&   r   r%   r'   r   r   r   r   _create_or_update_approve4   s(    
   z$CmfApprove._create_or_update_approvec           
      C   s  | ddddddddd	g	 g }| jd
|||jd}|jjD ]\}t|tjrf| jd|||jd|d}n(|j D ]}| jd|||jd|d}qp|	| q<|jj
D ]}| jd|||j|d}|jdkr|j}|sd}t|D ]&}	| jd|||jd|d}|	| q|d|jj|D ]*}| jd|||j|d|d}|	| q|d|jj|D ]*}| jd|||j|d|d}|	| qVqt|tjs| | t|drd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_membersfull)r   r   r#   r$   r
   grand_master)r   r   r#   r$   r&   r   r%   )r   r   r#   r$   r%   custom   r"   )r   r   r#   r$   r&   r%   	approvers)r   r   r#   r$   r%   r&   r   master_approversmaster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)Z	only_data)load_fieldsr+   r   r2   
isinstancer   	CmfPersonZdefault_membersloadr   approve_groupsrequired_signsmin_approversrangeZget_all_approversr,   valuer   r   hasattrr4   r    )
r   r   r#   created_approvesr   r   r
   app_grZmin_apprir   r   r   _create_approvesP   s      	
zCmfApprove._create_approvesc                 O   s   | j ||f|| d S N)rD   )r   r   r#   argskwargsr   r   r   start_approve_process   s    z CmfApprove.start_approve_processc                 O   s   |  | d S rE   )r!   )r   r   rF   rG   r   r   r   cancel_approve_process   s    z!CmfApprove.cancel_approve_processc                 C   s    t jj| j| jddgd}|jS )Nr-   r*   r   r#   r   r   )r   r   r   r   r#   r*   )selfZaggregr   r   r   approve_aggreg_result   s    z CmfApprove.approve_aggreg_resultc                 C   s8   |    |  }|dkr"| j  |dkr4| j  dS )u   
        Рассчитывает агрегаты и, если надо, двигает статусы объекта по БП
        approvedrejectedN)approve_calc_aggreg_resultrL   r   Z_approve_approvedZ_approve_rejected)rK   Z
app_resultr   r   r   _calc_status   s    
zCmfApprove._calc_statusc           
   
   C   s0  |  ddg | j}|j ddddddd	d
g |jjs<dS tjj| j| jdddddgd}tjj| j| jdd}dd |D }dd |D D ]}|j	|_	|
  qd}|jjD ]^}tjj| j| jd|d}| ||}	|	|_	|	dkrd}|
  |	dkrd|_	|
   dS q|rd|_	nd|_	|
  dS )u  
        Вычисляет статус результата утверждения всего объекта исходя из аппрувов и заполняет аппрувы-агрегаты
        :result: строка approved/rejected/in_approve
        TODO Есть возможность немного оптимизировать запихав все в один запрос, а так же не перезаполняя аггрегаты если они не менялись
        Пока что ТЗ постоянно меняется так что оставляю более читаемый вариант
        r   
obj.statusr1   need_approver2   r;   zapprove_groups.approverszapprove_groups.master_approverszapprove_groups.min_approverszapprove_groups.required_signsNr
   r&   r*   r%   r   rJ   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   r5   ar   r   r   r6      s
     
 
 
 z9CmfApprove.approve_calc_aggreg_result.<locals>.<listcomp>c                 S   s$   g | ]}|j d ks|j dkr|qS )rN   rM   r*   rS   r   r   r   r6      s     
 
 T)r   r#   r   r%   rM   FrN   
in_approve)r7   r   r   rR   r   r   r   r#   r   r*   r    r;   get_approve_group_status)
rK   r   r   Zaggreg_fullZfull_master_approver   Zall_approvedr%   Zaggreg_groupZapprove_group_statusr   r   r   rO      s>       
z%CmfApprove.approve_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   rQ   zobj.workflowzobj.approve_groupr&   r#   r   zapprove_group.required_signsr/   closed)r7   r   r%   r<   gZcurrent_userr   datetimeZnowZapproved_atr*   r   r    rP   )rK   r*   r   rG   r   r   r   _approve_one   s    zCmfApprove._approve_onec                    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 )r3   )r&   r%   rS   rB   r   r   r6      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 )rN   acceptedrM   rU   rS   r   r   r   r6   !  s
     
 
 
 c                    s$   g | ]}|j  kr|jd kr|qS )rN   )r%   r*   rS   r\   r   r   r6   %  s     
 
 rN   c                    s0   g | ](}|j  kr|jd ks&|jdkr|jqS )r]   rM   )r%   r*   r   rS   r\   r   r   r6   (  s
     
 
 
 Nr/   r0   ZfixedrM   rV   )r*   r=   r?   r<   lenr1   )r   rB   r   Zmaster_approvesr   Zapproved_approversr=   r   r\   r   rW     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   )
r7   r   r   Zis_newZ
is_changedr   r   r   Z	CmfNotifyZplace_notify)rK   messager   r   r   _place_notify;  s    
zCmfApprove._place_notifyc                    s   |    t j||S rE   )ra   superr    )rK   rF   rG   	__class__r   r   r    X  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   r9   r
   r(   Nr"   )
r   r   r#   r$   r   r   r   r*   r&   r%   CmfPersonGroup)r   ZCmfDocumentr   r7   Zget_in_approveZCmfApproveGroupsplitr9   r   Zdoc_versionr   r    r   rg   Z
rg_membersZ
all_nestedr8   r   r   )
r   r   r   r%   r#   rG   Zdoc_histrA   Zappr_prefixr   r   r   r   r   ^  sV    


zCmfApprove.add_approver)r
   NNNr"   NN)N)__name__
__module____qualname____doc__r   r   Zapi_methodsclassmethodr   r!   r+   rD   rH   rI   rL   rP   rO   r[   rW   ra   r    r   __classcell__r   r   rc   r   r      sD   	


       
]

/

(r   )Zcmfr   Zcmf.includer   rZ   r   r   r   r   r   <module>   s   