U
    r;dL                     @   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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
    c                 C   s   g }t jj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)code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_approve/   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}|	| qRq| | d S )Nr
   root_parentz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)load_fieldsr*   r   r1   
isinstancer   	CmfPersonZdefault_membersloadr   approve_groupsrequired_signsmin_approversrangeZget_all_approversr+   valuer   )
r   r   r"   created_approvesr   r   r	   app_grZmin_apprir   r   r   _create_approvesK   s      	zCmfApprove._create_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 r@   )r    )r   r   rA   rB   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_resultrG   r   Zapprove_success_fullZapprove_reject_full)rF   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.statusr0   need_approver1   r7   zapprove_groups.approverszapprove_groups.master_approverszapprove_groups.min_approverszapprove_groups.required_signsNr	   r%   r)   r$   r   rE   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   .0ar   r   r   
<listcomp>   s
     
 
 
 z9CmfApprove.approve_calc_aggreg_result.<locals>.<listcomp>c                 S   s$   g | ]}|j d ks|j dkr|qS )rI   rH   r)   rN   r   r   r   rQ      s     
 
 T)r   r"   r   r$   rH   FrI   
in_approve)r3   r   r   rM   r   r   r   r"   r   r)   r   r7   get_approve_group_status)
rF   r   r   Zaggreg_fullZfull_master_approver   Zall_approvedr$   Zaggreg_groupZapprove_group_statusr   r   r   rJ      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   rL   zobj.workflowzobj.approve_groupr%   r"   r   zapprove_group.required_signsr.   closed)r3   r   r$   r8   gZcurrent_userr   datetimeZnowZapproved_atr)   r   r   rK   )rF   r)   r   rB   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 )r2   )r%   r$   rN   r=   r   r   rQ     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 )rI   acceptedrH   rR   rN   r   r   r   rQ     s
     
 
 
 c                    s$   g | ]}|j  kr|jd kr|qS )rI   )r$   r)   rN   rY   r   r   rQ     s     
 
 rI   c                    s0   g | ](}|j  kr|jd ks&|jdkr|jqS )rZ   rH   )r$   r)   r   rN   rY   r   r   rQ     s
     
 
 
 Nr.   r/   ZfixedrH   rS   )r)   r9   r;   r8   lenr0   )r   r=   r   Zmaster_approvesr   Zapproved_approversr9   r   rY   r   rT     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   )
r3   r   r   Zis_newZ
is_changedr   r   r   Z	CmfNotifyZplace_notify)rF   messager   r   r   _place_notify/  s    
zCmfApprove._place_notifyc                    s   |    t j||S r@   )r^   superr   )rF   rA   rB   	__class__r   r   r   L  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

|}	|	  ||	 q| | dS )u  
        Добавляет либо один аппрув, если пришла персона, либо аппрувы всех членов группы персон или еще там какого орг.юнита
        :param obj_id: Объект, который аппрувим:
        :param approver_id: Персона или группа персон\подразделение итп:
        :param approve_group_id:   Аппрувгруппа
        )idr   :r   r5   r	   r'   Nr!   )
r   r   r"   r#   r   r   r
   r)   r%   r$   CmfPersonGroup)r   ZCmfDocumentr   r3   Zget_in_approveZCmfApproveGroupsplitr5   r   Zdoc_versionr   r   r   rd   Z
rg_membersZ
all_nestedr   )
r   r   r   r$   r"   rB   Zdoc_histr<   Zappr_prefixr   r   r   r   add_approverR  sT    


zCmfApprove.add_approver)r	   NNNr!   NN)N)__name__
__module____qualname____doc__classmethodr   r    r*   r?   rC   rD   rG   rK   rJ   rX   rT   r^   r   rf   __classcell__r   r   r`   r   r      s<   



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