B
    ۮ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}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	}	|	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}xl|jjD ]`}t|tjrh| jd|||jd|d}n,x*|j D ]}| jd|||jd|d}qtW |	| q>W x|jj
D ]}| jd|||j|d}|jdkr|j}|sd}x2t|D ]&}	| jd|||jd|d}|	| qW x@|d|jj|D ]*}| jd|||j|d|d}|	| q(W x@|d|jj|D ]*}| jd|||j|d|d}|	| qjW qW t|tjs| | t|drx$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_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   r1   
isinstancer   	CmfPersonZdefault_membersloadr   approve_groupsrequired_signsmin_approversrangeZget_all_approversr+   valuer   r   hasattrr3   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)rC   )r   r   r"   argskwargsr   r   r   start_approve_process   s    z CmfApprove.start_approve_processc             O   s   |  | d S )N)r    )r   r   rD   rE   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_resultrI   r   Z_approve_approvedZ_approve_rejected)rH   Z
app_resultr   r   r   _calc_status   s    
zCmfApprove._calc_statusc       
   
   C   s6  |  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 }x&dd |D D ]}|j	|_	|
  qW d}xh|jjD ]\}tjj| j| jd|d}| ||}	|	|_	|	dkrd}|
  |	dkrd|_	|
  dS qW |r$d|_	nd|_	|
  dS )u  
        Вычисляет статус результата утверждения всего объекта исходя из аппрувов и заполняет аппрувы-агрегаты
        :result: строка approved/rejected/in_approve
        TODO Есть возможность немного оптимизировать запихав все в один запрос, а так же не перезаполняя аггрегаты если они не менялись
        Пока что ТЗ постоянно меняется так что оставляю более читаемый вариант
        r   z
obj.statusr0   need_approver1   r:   zapprove_groups.approverszapprove_groups.master_approverszapprove_groups.min_approverszapprove_groups.required_signsNr	   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   )r4   ar   r   r   r5      s    z9CmfApprove.approve_calc_aggreg_result.<locals>.<listcomp>c             S   s$   g | ]}|j d ks|j dkr|qS )rK   rJ   )r)   )r4   rO   r   r   r   r5      s    T)r   r"   r   r$   rJ   FrK   
in_approve)r6   r   r   rN   r   r   r   r"   r   r)   r   r:   get_approve_group_status)
rH   r   r   Zaggreg_fullZfull_master_approver   Zall_approvedr$   Zaggreg_groupZapprove_group_statusr   r   r   rL      s8     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   z
obj.statuszobj.workflowzobj.approve_groupr%   r"   r   zapprove_group.required_signsr.   closed)r6   r   r$   r;   gZcurrent_userr   datetimeZnowZapproved_atr)   r   r   rM   )rH   r)   r   rE   r   r   r   _approve_one   s    zCmfApprove._approve_onec                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 )r2   )r%   r$   )r4   rO   )rA   r   r   r5      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 )rK   acceptedrJ   )r)   )r4   rO   r   r   r   r5   !  s    c                s$   g | ]}|j  kr|jd kr|qS )rK   )r$   r)   )r4   rO   )rA   r   r   r5   %  s    rK   c                s0   g | ](}|j  kr|jd ks&|jdkr|jqS )rV   rJ   )r$   r)   r   )r4   rO   )rA   r   r   r5   (  s    Nr.   r/   ZfixedrJ   rP   )r)   r<   r>   r;   lenr0   )r   rA   r   Zmaster_approvesr   Zapproved_approversr<   r   )rA   r   rQ     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   )
r6   r   r   Zis_newZ
is_changedr   r   r   Z	CmfNotifyZplace_notify)rH   messager   r   r   _place_notify;  s    
zCmfApprove._place_notifyc                s   |    t j||S )N)rZ   superr   )rH   rD   rE   )	__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

|}	|	  ||	 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   r8   r	   r'   Nr!   )
r   r   r"   r#   r   r   r
   r)   r%   r$   CmfPersonGroup)r   ZCmfDocumentr   r6   Zget_in_approveZCmfApproveGroupsplitr8   r   Zdoc_versionr   r   r   r_   Z
rg_membersZ
all_nestedr7   r   r   )
r   r   r   r$   r"   rE   Zdoc_histr@   Zappr_prefixr   r   r   r   r   ^  sN    
zCmfApprove.add_approver)r	   NNNr!   NN)N)__name__
__module____qualname____doc__r   r   Zapi_methodsclassmethodr   r    r*   rC   rF   rG   rI   rM   rL   rU   rQ   rZ   r   r   __classcell__r   r   )r\   r   r      s2         ^/
)r   )Zcmfr   Zcmf.includer   rT   r   r   r   r   r   <module>   s   