U
    <ad07                    @   s   d dl Z d dlmZ d dlmZmZmZ d dlmZ d dlT d dlZ	d dl
mZ G dd de	jjjjZejd	d
  ejdd
  dS )    N)copy)datetimetimezone	timedelta)
monthrange)*)cmfutilc                       s  e Zd Zed~ fdd	Z fddZ fddZedd	d
dZdd ZedddZ	ed fdd	Z
edddddddZedddZdd Zdd Zdd ZdddZed d! Zd"d# Zdd$d%Zeddd& fd'd(
Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zed3d4 Zed fd5d6	Zd7d8 Z fd9d:Zd;d< Zd=d> Z d?d@ Z!dAdB Z"dCdD Z# fdEdFZ$edGdH Z%dIdJ Z&dKdL Z'dMdN fdOdP
Z( fdQdRZ)dSdT Z*dUdV Z+edWdX Z,edYdZ Z-e.d[d\d]Z/d^d	d_d`Z0edadb Z1dcdd Z2ededf Z3edgdh Z4didje5dk fdldmZ6dndo Z7dpdq Z8eddrdsdtZ9eddudvdwZ:dxdy Z;ddzd{Z<e=d|d} Z>  Z?S )
CmfProjectNc                    sB   |dkr&|sg }|dd|gdddgg}t  j|f|||d|S )Ndefault_list	parent_id==cache_status_type!=closed)object_fields	object_idfilter)superfield_options_list)clsZrelation_field_namer   r   r   kwargs	__class__ './modules/project/models/cmf_project.pyr      s     zCmfProject.field_options_listc                    s   | j r
d S t   d S N)
logic_typer   _calc_logic_typeselfr   r   r   r      s    zCmfProject._calc_logic_typec                    s   | j r
d S t   d S r   )Z	scheme_wfr   _calc_scheme_wfr   r   r   r   r       s    zCmfProject._calc_scheme_wfzmodels.CmfTask)taskc                 C   s2  |j s"|jjs"|jjs"|jjs"d S |jjr@|js@|jr<g |_d S |jjr|jr|js|jsd }|jj r~d}|jj}|sd}|dg |jr|jjr|jjj	r|jjj	}|sd}t
jjdd|jjgdddggd	}|s
d
}t
jjdd|jjgdddggd	}|s8d}t
jjdddgdd|jjgggd	}|sfd}t
jjdddgdd|jjgggd	}|rt
j||dd  ||_|js|jjr|jr|jd j |_t
j|d|jd j dd  |jstjjrt
j|dtjj dd  tjj|_|jr.|dd | D  d S )Nu   SimpleLogic: Задача добавлена в проект, который установлен как "Проект/Раздел по-умолчанию" у исполнителяu   SimpleLogic: Задача добавлена в Структурный проект Главной роли исполнителяz8responsible.primary_role.structural_project.default_listu   SimpleLogic: Задача добавлена в проект, в котором исполнитель является владельцемcmf_owner_idr   project_typeprojectr   u   SimpleLogic: Задача добавлена в раздел, в котором исполнитель является владельцемsectionu   SimpleLogic: Задача добавлена в проект, в котором исполнитель является участником	executorsINu   SimpleLogic: Задача добавлена в раздел, в котором исполнитель является участником   )parenttextZ	log_levelr   ue   SimpleLogic: Задача добавлена в проект, полученный из списка u   SimpleLogic: Задача добавлена в проект, который установлен как "Проект/Раздел по-умолчанию" у пользователя, изменившего задачу - c                 S   s   g | ]}| d r|qS )zparent.)
startswith).0fr   r   r   
<listcomp>   s     
 z0CmfProject._calc_task_parent.<locals>.<listcomp>)is_newZlists
is_changedr*   ZresponsibleZdefault_projectloadload_fieldsZprimary_roleZstructural_projectmodelsr	   getidZ
CmfCommentsavenamegZcurrent_personcurrent_usersave_preload_fields)r   r!   Z
tmp_parentZ	sl_reasonr   r   r   _calc_task_parent#   s    




zCmfProject._calc_task_parentc                 C   s|   | j jsd S | j jr.d| j j_| j jjdd | j jrx| j jj  | j jj| kr^tddd d| j j_| j jjdd d S )NFTZ	only_datauc   Нельзя указать Спипок по-умолчанию из другого проектаabort)	r
   r1   oldZis_default_listr7   newr*   r2   	cmf_alertr   r   r   r   _calc_default_list   s    

zCmfProject._calc_default_listc                 K   s   t ddS tt| j|dgd}|s,g S |}g }|rX||jj |jj	dgd}q4ddd|gd	d|gg}	| 
 D ]2}
|
j}||}|r|| |	g||< qv|	||< qv| jf |d
d|}| j||dS )u_   
        Построение дерева от не корневого обьекта
        
DepricatedNtree_parentr   fieldsrG   ORtree_parent_idr(   r6   T)filtersfilter_projectrJ   )	Exceptiondictvarsr4   r5   appendr6   valuerE   r2   _get_node_models
class_name_get_tree_dataZ_create_tree)r   Z	obj_modelZ
obj_filterrK   rJ   r   objr*   Z
parents_idZparent_filtermodel
model_namemodel_filter	tree_datar   r   r   get_obj_tree   s*      

zCmfProject.get_obj_treer$   c           	         sx   t dd S ddd|gdd|gg}|  D ]2}|j}||}|rT|| |g||< q*|||< q*t j||fd|i|S )NrD   rI   rJ   r   r6   rK   )rN   rO   rS   rT   r5   r   get_tree_leaf)	r   rJ   r#   rK   r   Zparent_filtrW   rX   rY   r   r   r   r\      s      

zCmfProject.get_tree_leaf)rG   rK   r#   rL   c                O   s   t dd S |rdd|g}|drF|r8||dg}n|rF|d}dtjj||| ddgdi}	|D ]H}
tt|
 }||
 pg }|tjkr|ddd gg}|j||jd |	|
< qh|	S )!NrD   ordernor8   r"   	cmf_ownerr#   show_approved
show_tasksshow_archive
show_pfeed	show_disk	show_chat	show_epicshow_sprintshow_releaseshow_roadmapactivitycmf_owner_assistantsZhas_tree_nodestree_hidden	is_publicsharelink_hashperm_policy_anonymousperm_policy_guestperm_policy_sharelinkperm_policyr   r	   )r   rG   Zorder_bysys_type=rF   )	rN   r5   popr4   r	   listrP   CmfListZtree_fields)r   rG   rK   r#   rL   argsr   Zproject_filterZproject_fieldsrZ   rX   rW   rY   r   r   r   rU      sh                                 


 
zCmfProject._get_tree_datac                 C   s   t dd S D ]"}|jdkr|jjjdd d q|r||	dd	  D ]>}|j
|krHt|d
shg   S t|tjr||| |g  S qHg S |tjj D ]}|| q|tjj S )NrD   c                 S   s   t | jjD ]~}d|jkrZt|dd rZd|j | jkrZt| d|j dsZ| jj| t|tj	rd| jkrt| dds| jj| qd S )Nrr   show_Trd   )
r   
tree_nodesrR   rG   getattrrr   remove
isinstancer4   CmfChatGroup)r$   noder   r   r   hide_project_parts  s"    


z5CmfProject._get_tree_root.<locals>.hide_project_partstagsc                 S   s   | j S r   r8   )r~   r   r   r   <lambda>)      z+CmfProject._get_tree_root.<locals>.<lambda>)key:r   ry   )rN   r5   r4   	CmfFolderrT   rr   ry   rR   sortsplitr6   hasattrr|   r	   )r   rZ   rJ   r   folderrV   r$   r   r   r   _get_tree_root  s$     



zCmfProject._get_tree_rootc                 C   s4   t jj| dd}|s0t j| ddddd}|  |S )Ntrashcan)r*   rr   u   КорзинаT)rE   r8   rr   systemrk   )r4   r   r5   r7   )r   r   r   r   r   scaffold_trashcan8  s
    zCmfProject.scaffold_trashcanc                 C   s8   d}t j| |d}|  t j| d|dd}|  |S )NzX[lists, EXISTS, [[cache_status_type = IN_PROGRESS], [logic_prefix = list.agile_sprint]]]r*   ft_add_ubqlu   Активные спринтыT)rE   r8   Zkanban_filterr   )r4   CmfTaskFilterr7   ZCmfKanbanBoard)r   r   Zactive_sprints_filterZactive_sprints_boardr   r   r   scaffold_active_sprints?  s    z"CmfProject.scaffold_active_sprintsc                    s  d9dd}d}| j dkrd}|| tjtddt|| dd	d
d}||tjtddtddd}||tjtddtdddd}|jD ]<}t|tjr|jr|jj| jkr|j	dkr|jj
| q||tjtdddtd| dd tjtjd}	|	jddddddd  fddtddD }
dd |
D }t|
|}d d!d"d#d$d%d&d'd(d)d*d+d,}|D ]:\}}||tjt||d-d.td/||j  | dd qZ||tjtd ddd0d1td2| dd ||tjtd3d4d5td6| d7d8d d S ):Nc                    sf   | j D ]0 t |rt fdd| D r   S q|f d| i||}|  | j j| |S )Nc                 3   s   | ]\}} | |kV  qd S r   r   )r-   kvir   r   	<genexpr>U  s     zNCmfProject.scaffold_backlog.<locals>.add_node_if_not_exists.<locals>.<genexpr>rE   )ry   r|   allitemsr7   rR   rQ   )rE   
node_classnode_filter_kwargsnode_create_kwargsr~   r   r   r   add_node_if_not_existsN  s    
$
z;CmfProject.scaffold_backlog.<locals>.add_node_if_not_existsu   Задачиproject.agileZBacklogbacklog)rr   順 T)r8   filter_parentr]   r   )rE   r   r   r   r   u   Тэгиr   Zdatesu   Даты
   )r8   r]   r   ZfalseZnot_assigned)filter_responsible_setrr   u   #НеНазначено)r8   r   Ztz   )monthdayhourminutesecondZmicrosecondc                    s   g | ]} j |d qS ))r   )replacer-   r   Zstart_of_yearr   r   r/     s     z/CmfProject.scaffold_backlog.<locals>.<listcomp>   c                 S   s,   g | ]$}|j t|j|jd  ddddqS )r      ;   )r   r   r   r   )r   r   Zyearr   r   r   r   r   r/     s   u   Январьu   Февральu   Мартu   Апрельu   Майu   Июньu   Июльu   Августu   Сентябрьu   Октябрьu   Ноябрьu   Декабрь)r   r)                     	   r         date)Zfilter_plan_start_date_minZfilter_plan_start_date_maxrr   #Zno_alarm_date)r   Zfilter_plan_start_date_setZfilter_alarm_date_setrr   u   #БезДатыFZnot_approved)Zfilter_approvedrr   u   #Согласоватьu  В фильтр "#Согласовать" попадают все идеи, пожелания, задачи от пользователей.
Руководитель проекта обрабатывает список и переносит задачи в другие списки.
В идеале этот список должен быть обработан, то есть оставаться пустым к концу рабочего дня руководителя проекта.

примеры  списков, куда можно перенести задачи из "#Согласовать":
todo0 Срочно до мвп
todo1 В течение года
todo2 Через год
Отклонено
Версия октябрь 2021)r8   r   r+   )NNNN)logic_prefixr4   r   rO   ry   r|   CmfActiveEntityFilter
filter_tagri   Zcache_select_countrR   r{   r   nowr   utcr   rangezipr   )r   rw   r   r   Zfld_tasks_nameZ	fld_tasksZfld_tagsZ	fld_datesr~   r   Zstarts_of_monthsZends_of_monthsZmonth_rangesZmonth_namesZmonth_startZ	month_endr   r   r   scaffold_backlogL  s        


	
     

zCmfProject.scaffold_backlogc                 C   s   |s
| j }d| S N/r   r   r8   r   r   r   project_dir  s    zCmfProject.project_dirc                 C   s   t jjj }|| S r   )r4   CmfRFileZdpZdata_driverZget_rdZ	get_rfile)pathZrdiskr   r   r   
_get_rfile  s    zCmfProject._get_rfilec                 C   s   |  |  jdddd dS )u   Создадим папку проекта, если её нет. Может так же нужно проверять "Документы"? T)is_direxist_okparentsN)r   r   creater   r   r   r   ensure_project_dir  s    zCmfProject.ensure_project_dirc                 C   s   |s
| j }| | |jS r   )r8   r   r   existsr   r   r   r   is_project_dir_exist  s    zCmfProject.is_project_dir_existr#   rK   c                   sB   t dd S t jf ||d|}|D ]}|  |  q(|S )NrD   r   )rN   rO   r   get_full_treer   r   )r   r#   rK   rw   r   resr$   r   r   r   r     s      
zCmfProject.get_full_treec                 C   s	  t jjdd}t jjdd}t jjdd}t jjdd}t jjdd}td dd	lm} |d
g  }| jdkrz|   | j	st 
 }t jjdd|_| |_d| j |_d|_|  || _	t j| dddd|_t j| dddd|_t j| dd| j d|dd|_t j| | gd| j dd|_|  |_| jdkr*t jjd| jd|_t j| dd|_t j| dd d!|_t j|jd"d|_d#|j_d$|j_d%|j_d&|j_d'|j_d(|j_d)|j_d|j_ d|j_ d|j_ d|j_ d|j_ d|j_ |j!" D ]}	|	  qd*| _#d*| _$d*| _%d*| _&| jdd+ | jd,krt j| d-d.dd|_'t j
| |j'd/|d0|_(t j| d1d2dd|_)t j|j)d3d4|d5|_*t j| d6d7dd|_+t j|j+d8d9|d5|_,t j| d:d;dd|_-t j.|j-d<dd=|_/t j| dd d!|_t j|jdd|_0| 1 |_2t jjd| jd|_t j| d>d?dd|_3t j4|j3d@d|_5t j4|j3dAd|_6t j| dBdCdd|_7d#|j_dD|j-_dE|j'_d$|j+_d%|j)_d&|j2_dF|j_d'|j3_d(|j7_dG|j_dH|j_dI|j_dJ|j_d)|j_d|j_ d|j_ d|j_ d|j_ |j!" D ]}	|	  qd| _8d| _9d| _:d| _;d| _<d| _=d| _$d*| _#d*| _%d*| _&d| _>d| _?| jdd+ t j@jAjB}
|
D ],}t j@|
| |j7||j5dK|_C|jC  qv| jdLkrXt jjd| jd|_t j| dMd d!|_Dt j|jDdNd4|d4dO|_Et j| dd d!|_t j|jdd|_0t j| d>d?dd|_3t j4|j3d@d|_5t j4|j3dAd|_6t j| dBdCdd|_7d#|j_dD|jD_dE|j_d$|j_d%|j_d&|j3_dF|j7_d'|j_d(|j_d)|j_d|j_ d|j_ d|j_ |j!" D ]}	|	  qd| _8d| _9d| _#d| _$d*| _%d*| _&d| _>d| _?| jdd+ t j@jAjB}
|
D ],}t j@|
| |j7||j5dK|_C|jC  q*| jdk	r| FdPdQ}| FdRdS}| FdTdU}dVdWdXt jjdYddZ|||d[d\d]t jjdYddZ|||d[d^d_t jjd`dda|||d[dbdct jjd`dda|||d[gddded\d]t jjdYddZ|||d[dfdgt jjdYddZ|||d[gddg}| G| | jHdhdit jjdjddk t j| dldmdd|_It j4dn| do|_Jt jK|jI| |jJdpdq|_Lt j4| drds|_Mt jK|jI| |jMdtdq|_Nt j4| duds|_Ot jK|jI| |jOdvdq|_Pt j| dwdxdyddz|_Qt j|jQd{d|d!|_Rt j|jQd}d|_St j| dBdCdd|_7t j| d>d?dd|_3t j4|j3d@d|_5t j4|j3dAd|_6t j| d~ddd|_Tt j| dddd|_Ud#|jI_dD|jQ_dE|jT_d$|jU_d%|j3_d&|j7_dF|j_d'|j_d(|j_dG|j_d|j_ d|j_ d|j_ d|j_ d|j_ |j!" D ]}	|	  	q&d*| _8d*| _9d*| _#d*| _$d*| _%d*| _&d*| _Vd| _Wd| _Xd| _Yd| _Zd| _>d| _?| jdd+ t j@jAjB}
|
D ]8}|[d	rt j@|
| |j7||j5dK|_C|jC  	q| \  | ]  d S )uU    Добавляем структуру папок в новый проект
        zlist.pfeed:defaultcodeztask.epic:defaultzlist.agile_sprint:defaultzlist.release:defaultzlist.base:defaultuc   Вызываем разворачивание чтобы появилась папка задачиr   )make_dataclassZ	DataEmptyproject.servicedeskztask.gantt_project:defaultu	   Гант Tu   Дискdisk)rE   r8   rr   r   u
   Архивarchiveu
   Лентаu   Лента проекта pfeed)rE   r8   r+   	list_typer   r   u   Чат )rE   r'   r8   r   zproject.wikir   )rr   rJ   u   Документ1)rE   r8   u   ДокументыN)rE   r8   rr   u   Документ2r   i i" iI i i  i Fr=   r   ZEpicsepiczEpic 1)r*   rE   r8   r   ZSprintssprintzSprint 1Zkanban)rE   r8   r   r   ZReleasesreleaseu   Релиз 1ru   ZRoadmapsroadmapu   Roadmap Проекта)rE   r8   r   u   ФильтрыrK   u   Фильтр 1u   Фильтр 2u   Отчетыreportsi i i q i0 i@ iP4 i`[ )r8   rE   report_typeZreport_filterzproject.baseu   В работеu   Канбан1)rE   r8   r   r   ui_view_formzui_form.sd_view:defaultu   Просмотрzui_form.sd_create:defaultu   Созданиеzui_form.sd_view_inner:defaultu(   Просмотр в приложенииu
   Общееu"   Получить ИТ помощьuZ   Получите помощь по общим ИТ-проблемам и вопросам.ztask.sd_service_request:defaultzservice-requests)r8   r+   r   categoryui_form_viewui_form_createui_form_view_inneru9   Запросить новую учетную записьuP   Запросите новую учетную запись для системы.u7   Сообщить о системной проблемеu   Дайте нам знать, если что-то не работает должным образом, и постарайтесь быстро восстановить его работоспособность.ztask.sd_incident:defaultZ	incidentsu?   Сообщить о сломанном оборудованииu   Сообщите об оборудовании, которое может быть неисправным или сломанным, например разбитый экран компьютера или поврежденный сервер.)r8   typesu+   Логины и учетные записиu<   Запросить доступ администратораuY   Например, если вам нужно администрировать EvaProject.u3   Запрос по электронной почтеuu   Запрос получен от вашего канала поддержки по электронной почте.ztask.sd_emailed_request:default)r8   r+   r   u   Очередиqueuez[cache_status_type != CLOSED])r   r*   u   Все обращения)rE   r*   Ztask_filterr8   z?[responsible = __G_CURRENT_USER], [cache_status_type != CLOSED]r   u   Назначенные мнеz[cache_status_type = CLOSED]u#   Закрытые обращенияu   База знанийknowlage_basereadonly)rE   r8   rr   ro   r   u   КатегорииZknowlage_base_categoriesu   Статьиu   Каналыservicedesk_channelsu   Клиентыservicedesk_clientsZanalysis)^r4   ZCmfLogicTyper5   ZlogginginfoZdataclassesr   r   r   Zmain_gantt_projectCmfTaskr   r*   r8   r   r7   r   r   r   rv   r   r}   chatr   r   r6   r   CmfDocumentZdoc1ZdocsZ
docs__doc2r]   rk   __dict__valuesrc   ra   rb   rd   ZepicsZepics__epic1ZsprintsZsprints__sprint1ZreleasesZreleases__release1ZroadmapsZ
CmfRoadmapZroadmaps__roadmap1Z
docs__doc1r   Zkanban_boardrK   r   Zfilters__filter1Zfilters__filter2r   r`   r_   rh   re   rg   rf   Zshow_filtersZshow_reportsZCmfTaskReportr   choicesZreports__report1Zin_workZin_work__kanban1_create_ui_view_form_create_sdesk_request_group_create_sdesk_request_typer   Zqueue__queue1_task_filterZCmfTaskQueueZqueue__queue1Zqueue__queue2_task_filterZqueue__queue2Zqueue__queue3_task_filterZqueue__queue3r   Zknowlage_base__categoriesZknowlage_base__articlesZchannelsZclientsZshow_trashcanZ
show_queueZshow_knowlage_baseZshow_servicedesk_channelsZshow_servicedesk_clientsr,   _create_assign_to_project_create_sdesk_sla)r   Zlt_pfeedZlt_epicZ	lt_sprintZ
lt_releaseZlt_baser   tZgantt_projectr   r   itemZ_ui_form_viewZ_ui_form_createZ_ui_form_view_innerZrequest_groupsr   r   r   scaffold  s   

  
                

 
 

,
D

 
 
 
    
 zCmfProject.scaffoldc                 C   sb   t jj|dgd}|s(td| dd t  }| j d| j d| |_|j|_|jdd |S )Nui_form_json)r   rG   u3   Отсутствует экранная форма Tr>   z: r=   )r4   Z	CmfUiFormr5   rB   task_code_prefixr8   r   r7   )r   r   action_nameZui_formZ_ui_formr   r   r   r   s  s    zCmfProject._create_ui_view_formc                 C   sn   t jjdd}t jjdd}t  }| |_||_|jtj	 |j
dd t  }| |_||_|j
dd d S )Nsdesk-client:defaultr   sdesk-agent:defaultTr=   )r4   ZCmfProjectRoler5   CmfProjectRoleAssignr*   Zproject_rolemembersrQ   r9   r:   r7   )r   Zsdesk_clientZsdesk_agentZprr   r   r   r   }  s    z$CmfProject._create_assign_to_projectc                 C   s  t jjdd}t j| ddd}|jdd t j|dd	d
|d}|jdd t j|ddd|d}|jdd t j|ddd|d}|jdd t j|dd d|d}|jdd t j|ddd}|jdd t j|ddd}|jdd t j|ddd}	|	jdd t j| ddd}|jdd t j|ddd
|d}|jdd t j|dd	d|d}|jdd t j|dd d|d}|jdd t j|ddd}|jdd t j|ddd}|jdd t j|ddd}	|	jdd t j|ddt jjddd}
|
jdd t j| d dd}|jdd t j|dd!d"|d}|jdd t j|dd d|d}|jdd t j|ddd}|jdd t j|ddd}|jdd t j|ddt jjd#dd}	|	jdd t j| d$dd}|jdd t j|dd!d%|d}|jdd t j|dd d|d}|jdd t j|ddt jjd&dd}|jdd t j|ddt jjd#dd}|jdd t j|ddt jjd'dd}	|	jdd t j|ddt jjd(dd}
|
jdd t j|ddt jjd)dd}|jdd d S )*Nzfulltime:defaultr   u   Время решенияr   )r*   r8   Zwidget_typeTr=        z+request_type.request_category = 'incidents')r*   r]   Z	goal_timeZubqlcalendari  i  z2request_type.request_category = 'service-requests'i  i`	  z7request_type.request_category = 'post-incident-reviews'i   startzissue-created)r*   trigger_typetrigger_conditionzresolution-clearedstopzresolution-setu+   Время до первого ответаx   zcomment-for-reporterzstatus-type-changedZsd_waiting_for_customer)r*   r	  r
  Ztrigger_condition_status_codeu;   Время закрытия после разрешенияi  zBrequest_type.request_category in ['incidents', 'service-requests']r   u/   Время на проведение ревьюz)request_type.request_category = 'changes'Z	in_reviewZsd_declinedZsd_implementingZsd_planning)r4   ZCmfCalendarr5   ZCmfSDeskSlar7   ZCmfSDeskSlaGoalZCmfSDeskSlaTriggerZCmfStatusCode)r   Zdefault_calendarZslaZgoal1Zgoal2Zgoal3Zgoal4Ztrigger1Ztrigger2Ztrigger3Ztrigger4Ztrigger5r   r   r   r     s    
 
 
 
 
 

 

 




zCmfProject._create_sdesk_slac                 C   sZ   t jjdd| jgdd| jggdr8td| j ddd	 |  rVtd
| j ddd	 d S )Nr8   rs   r6   r   r%   u   Проект с именем uA    уже существует. Укажите другое имя.Tr>   u-   Раздел на диске с именем uF    уже занят. Укажите другое имя проекта.)r4   r	   Zslistr8   r6   rB   r   r   r   r   r   _check_project_dir_conflict  s    "z&CmfProject._check_project_dir_conflictc                 C   sF   ddd|gg}|r"| dd|g | j|drBt| j ddd d S )	NrI   r8   r   r   r%   u7    с таким именем уже существуетTr>   )rQ   r5   rB   Zverbose_name)r   r8   r   Z
prj_filterr   r   r   _check_unique  s
    zCmfProject._check_uniquec                    s$   |  || t j|||d|S )N)r8   r   )r  r   r   )r   r8   r   rw   r   r   r   r   r     s    zCmfProject.createc                 C   sR  ddddddddd	d
dddddddg}ddg}|D ]}d| }| j | jr2|D ]|}tt| jdd| jgdd|ggd}|s|dkrtt| jdd| jgdddggd}|rP| j | j |_|jdd qPtj	jdd| jgddd| ggd}|r2| j | j |_|jdd q2| j
jrNtjjdd| jgd}| j
j |_|jdd d S ) NtasksZapprovedr   r   r   r   r   r   r   r   r   r   r   rK   r   r   r   r   r   rx   r   r   rr   r%   r   Tr=   r   zlist.rJ   rs   )r   r1   rP   r4   r5   r6   rR   rk   r7   rv   rd   r}   )r   Z	sys_typesZnode_modelsrr   Z	fieldnameZ	nodeclassZsysnoder   r   r   _calc_hidden_nodes  sV    

zCmfProject._calc_hidden_nodesc              	      s   t   ddddddddg S )	NZdefault_list_workflowZdefault_epic_workflowZdefault_subproject_workflowZdefault_release_workflowZdefault_sprint_workflowZdefault_document_workflowZdefault_task_workflowproject_perm_scheme)r   r;   r   r   r   r   r;   0  s    zCmfProject.save_preload_fieldsc                 C   sN   | j js| jjrtd | jdkr(d| _| jdkr:d| _n| jdkrJd| _d S )Nu<   Нельзя менять родителя у проектаr&   zCmfWiki:Classr$   zCmfProject:Class)r*   r1   rE   rB   r#   r   rJ   r   r   r   r   _calc_parent<  s    


zCmfProject._calc_parentc                 C   s(   | j jsd S tj| j j| jj| _ d S r   )r+   r1   r4   r   Zconfluence_convertrR   r6   r   r   r   r   
_calc_textG  s    zCmfProject._calc_textc                 C   s,  | j js| jjsd S | j jr| j j | _ | j dksT| j dksT| j dksT| j | jkrhtd| j  dd tjj	dd| j
gd	d
| j ggdgdd}|rtd| j  d|j ddd tjj	dd| j  dgdd| ggdgdd}|rtd| j  d|jj d | jr
d S td ttjj| j
jgd d S )NTSKAZ	NOPROJECTuH   Нельзя использовать системный префикс Tr>   r6   r   r   rs   r8   )r   rG   Zinclude_deletedu   Код u2    уже используется проектом u   . Выберите другойr   ZLIKEz-%r$   zproject.nameu8    ранее использовался проектом u   . Это может привести к пропускам в нумерации кодов. Если это нежелательно - укажите другой префиксur   Запущен фоновый процесс смены префиксов кодов у задач проекта)rw   )r   r1   Ztask_code_use_logic_type_prefixrR   upperZcode_prefixrB   r4   r	   r5   r6   r8   ZCmfTaskCodeHistoryr$   r0   Zcmf_deferred_taskr   Zrecalculate_codes_celery)r   Zproject_with_prefixZ	code_usedr   r   r   _calc_task_code_prefixL  sF    

z!CmfProject._calc_task_code_prefixc                 C   s   |    d S r   )Z_check_simple_permr   r   r   r   check_simple_permz  s    zCmfProject.check_simple_permc                 C   s   ddl m} | j  || jjp"dddd}dd td	|D d
d }t|dkrh|d d
d }nddd |D }d|	  }d}t
jjdd| | gdd| jggdr|sd}|d7 }q| | | _d
S )u  
        Генерируем автоматически Префикс для кода задач для Разделов (там он не очень важен)
        TODO1: возможно, выводить на форме создания разделов поле ввода Префикса
        Важно! Этот метод разрешен только для Разделов!
        r   )translitr  ruT)Zlanguage_codereversedc                 S   s   g | ]}|r|qS r   r   r-   cr   r   r   r/     s      zACmfProject._calc_task_code_prefix_for_section.<locals>.<listcomp>z(?:\b|_)([A-Za-z0-9]{1,4})Nr   r   r  c                 s   s   | ]}|d  V  qdS )r   Nr   r  r   r   r   r     s     z@CmfProject._calc_task_code_prefix_for_section.<locals>.<genexpr>ZWIKIr   rs   r6   r   r%   )Ztransliterater  r8   r2   rR   refindalllenjoinr  r4   r	   sgetr6   r   )r   r  r   Z	code_listr   r   r   r   "_calc_task_code_prefix_for_section}  s     

z-CmfProject._calc_task_code_prefix_for_sectionc           
         s(  | j r~tjjdd| jgdd| jggd}|rDtd| j ddd	 n:|  r~| | 	 }|j
r~|d
| j dt d | jjrt| jj| _| jjrt| jj| _d}| jjr| jstd |   | jjr| | jjr| | 	| jj}|| 	  | j r*| js&| j| _d}| j s:|   | jsp| jdkr`tjjdd| _ntjjdd| _|   |   | js| jdkr|   ntddd	 |    t! j"||}| j s| jjrtj#  |r| $  tj%j&ddddggdgd}|D ]}	d|	_'|	j"dd q
|S )Nr8   r   r6   r   r%   u   Проект u    уже существуетTr>   r   _z%Y-%m-%d-%H%M%SFu<   Имя проекта не может быть пустым.r   zservicedesk:defaultr   zsystem:defaultr&   u8   Укажите Префикс для кода задачonboarding_statuszNOT INr   cancelrF   r=   )(r0   r4   r	   r5   r8   r6   rB   r   r   r   r   renamer   r   document_header_textr1   r   Z
clean_textrR   document_footer_textr  r@   r   r  r  r   CmfProjectPermSchemer  rC   r   r#   r#  r  r   r7   Ztrigger_reloadr   Z
CmfLicenseru   r%  )
r   rw   r   r   Zproject_dir_rfileZshould_be_scaffoldedZ	old_rfileresultZonboardingsZ
onboardingr   r   r   r7     s^    "


zCmfProject.savec                 C   s  t t|dd }|j|ddgd}|o<t t|dd }|oP|j|dgd}|r^|jjp`d}|oxt t|dd }	|	o|	j|dgd}
|
r|
jjpd}d}|jr|jjjdkr|jjrd}|r|	  |r|r|t
|| d	  |_n |r|d
 |_n|r|d
 |_|jdd d S )Nr   r   r]   zparent.disable_simple_perm)r6   rG   Tr	   Fr)   r  r=   )rz   r4   r   r5   r]   rR   r*   rT   Zdisable_simple_permZcheck_owner_permsintr7   )r   Zitem_idZ	anchor_idZnext_idZ
item_modelr   Zanchor_modelZanchorZanchor_ordernoZ
next_modelZ	next_itemZnext_ordernoZneed_check_owner_permsr   r   r   	move_item  s*    
zCmfProject.move_itemc                 C   s   d S r   r   r   r   r   r   
_calc_code  s    zCmfProject._calc_codec                 C   s   d S r   r   r   r   r   r   get_code_prefix  s    zCmfProject.get_code_prefixT)	recursivec                   sD   | j j}t j|d|i|}| |r@tj|}|r@|  |S )Nr0  )	r8   rR   r   deleter   r4   r   r5   Zmove_to_trash)r   r0  rw   r   Zcur_namer   r   r   r   r   r1    s    
zCmfProject.deletec                    s(   t  jf |}tj| jj|   |S r   )r   restorer4   r   Zrestore_from_trashr8   rR   r   )r   r   r   r   r   r   r2    s    zCmfProject.restorec                 C   sT   t jtjd}|tdd7 }tjjdd| jgdd|gdd	d
gddd ggdgd}|S )Nr   r   )Zhoursr   r   plan_start_date<r   r   ZCLOSED
alarm_dater   rF   )	r   r   r   r   r   r4   r   ru   r6   )r   r   r  r   r   r   _list_tasks_need_to_start  s    
z$CmfProject._list_tasks_need_to_startc              	   C   s`   | j r
d S |  }|sd S td| jjj  tjj| jj	d| d| j d| j j
 ddd d S )Nu&   Отправляем карточку u   Рекомендацияu   
            В проекте u(   есть задачи с планом, но без будильника.
            Назначьте будильник, или список с планом,
            чтобы задачи появились у исполнителя в ленте.
            (сброшен флаг "z")
            r)   )Z	person_idr8   rV   msgpriority)auto_alarm_dater6  printr^   r8   rR   r4   Z	CmfNotifyZplace_notifyr6   Zcaption)r   r  r   r   r   '_notify_project_owner_not_planned_tasks  s"    z2CmfProject._notify_project_owner_not_planned_tasksc                 C   s:   t jjddD ]&}| }|D ]}|j|_|  qqd S )NT)r9  )r4   r	   ru   r6  r3  r5  r7   )r   r$   r  r!   r   r   r   _cron_auto_alarm_date5  s
    z CmfProject._cron_auto_alarm_datec                 C   s    | j dgdD ]}|  qd S )Nz**rH   )ru   r;  )r   r$   r   r   r   &notify_project_owner_not_planned_tasks>  s    z1CmfProject.notify_project_owner_not_planned_tasks)	task_tagsc           
      C   s  |sdS dd |D }t jj| jdd}t jj| jdd}|rB|sFdS dd t jj|jdD }t jjd	d
gdd| jgdddggdD ]}|jj|kr||jj}|j	
 r
||j	jj}|st j| ||j	jd }|||j	jj< |j|jkr&|j|_|  q|j|jkr|j|_|  q| D ]\}	}|j	rt|  d| d|j	  ||j	jj}|st j| ||j	jd }|||j	jj< t j|d|j d| |d}|  n8t|  d|  t j|d|j d| |d}|  q0dS )u   
        Вызывается если у задачи проекта изменяются тэги.
        Если появился тэг, для которого нет фильтра - создадим его.
        TODO
        Nc                 S   s   i | ]}|j j|qS r   )r6   rR   )r-   tagr   r   r   
<dictcomp>L  s      z5CmfProject.hook_task_tags_changed.<locals>.<dictcomp>r   )r   rr   r   c                 S   s   i | ]}|j j|qS r   )r8   rR   )r-   r   r   r   r   r@  Q  s    rM   filter_tag_idrJ   r   r   rr   r?  rG   r   )r*   rE   r8   z: Create new filter for z with category r   )rE   r8   rr   r   r   )r4   r   r5   r6   ru   r   rA  rR   rt   Ztag_categoryr2   r8   r7   rJ   r   r9   debug)
r   r>  Ztask_tags_id_dictZtasks_filterZtags_folderZcategory_foldersZ	ae_filterr?  Zcategory_folderZtag_idr   r   r   hook_task_tags_changedC  sv    
  


  
 
  
 
   z!CmfProject.hook_task_tags_changedr   c                 C   s   d S r   r   )r   r!   r   r   r   hook_task_save  s    zCmfProject.hook_task_savec                 C   s   d S r   r   )r   r?  r   r   r   hook_new_tag  s    zCmfProject.hook_new_tagc                 C   s   dS )NTr   r   r   r   r   has_tree_nodes_hook  s    zCmfProject.has_tree_nodes_hookc                 O   s   d S r   r   )r   rw   r   r   r   r   public_list  s    zCmfProject.public_listc                 O   st   ddddddddd	d
dddddddddddddddg}||d< t jj||}z|  W n tk
rn   Y d S X |S )Nr6   r8   r   r"   rj   activity_idr   r   zworkflow.namer^   Zcmf_created_atr#   r   descriptionrl   rm   rn   ro   rp   rq   r+   Zpublic_html_schemer(  r)  rG   )r4   r	   r5   Z_acl_check_readZCmfPermissionError)r   rw   r   Zfields_to_returnr$   r   r   r   
public_get  sH     zCmfProject.public_getr   )	recursion)returnc             	      sf   t  }| dddddddg | jr8|t |   n|| j| jh t j|d|i||S )	Nzfollowers.personzfollowers.notify_volumezfollowers.follow_childrenrE   notify_all_personsr^   cmf_owner_assistantrL  )	setr3   rN  unionZall_relation_personsr^   rO  r   get_all_followers)r   rL  rw   r   r   r   r   r   rR    s       zCmfProject.get_all_followersc                 O   s   t jj| f||S r   )r4   r*  check_project_role_access)r   rw   r   r   r   r   rS    s    z$CmfProject.check_project_role_accessc                 C   sb   | j s| jsd S | j rd S | jr^| jdd}|  D ]}||kr4|| q4|r^| jd| d d S )NT)r1   zPPP-PR-ADMINrV   )r0   r1   keysZproject_perm_allow_fieldsr{   rS  )r   Zchanged_fieldsZallowed_fieldr   r   r   _check_project_perm  s    zCmfProject._check_project_permr%   c                O   s   dddg}g }|rd|kr|}dddgg}dddg}t jjd	ddgd
dtjgggd}t jjdgddddggdddtjggdd|gggd}dddd |D g}	|d||	g || t jj||d}
t	dd |
}t|S )Nr8   r   r+   r   rs   r   Zservicedesk_publicTZservicedesk_allowZpersonsr(   r%   r*   zproject_role.coder   r  rI   r  rB  r6   c                 S   s   g | ]
}|j qS r   )r   )r-   pr   r   r   r/     s     z)CmfProject.sdesk_list.<locals>.<listcomp>c                 S   s   | j d| ddS )NPPP-PR-BROWSEF)rV   Zraise_error)rS  )rW  r   r   r   r     r   z'CmfProject.sdesk_list.<locals>.<lambda>)
r4   Z
CmfCompanyru   r9   r:   r  rQ   r	   builtinsr   )r   r   rw   r   rG   Zsearch_filterZfilter_1Zcompany_listZproject_assign_listZfilter_2Zproject_listZfiltered_project_listr   r   r   
sdesk_list  s:    



zCmfProject.sdesk_listrH   c                   sp   ddddddddd	d
dddddddg |s.g }t t fdd|}| j|d|i|}|rl|jd|d |S )Nr6   r   r8   r   r+   rJ  r"   rI  r   r   r^   r#   r   Zshow_tree_iconsZui_modelr   Zallow_edit_commentsc                    s   |  kS r   r   )r.   Zallowed_fieldsr   r   r      r   z&CmfProject.sdesk_get.<locals>.<lambda>rG   rX  rT  )ru   rY  r   r5   rS  )r   rG   rw   r   r$   r   r[  r   	sdesk_get  s2    zCmfProject.sdesk_getc                 C   s   |D ]z}t  }| |_|d|_|  |dD ]H}| j|d|d|d|d||d|d|dd	 q4qd S )
Nr8   r   r+   r   r   r   r   r   )r8   r+   r   r   groupr   r   r   )r4   ZCmfSDeskRequestGroupr*   r5   r8   r7   r   )r   groupsr]  request_grouprequest_typer   r   r   r   '  s     z&CmfProject._create_sdesk_request_groupc	           
      C   sd   t  }	| |	_||	_||	_||	_||	_||	_||	_|d k	r@||	_	|d k	rT|	j
| |	jdd d S )NTr=   )r4   ZCmfSDeskRequestTyper*   r8   r+   r   r   r   r   Zrequest_categoryr_  rQ   r7   )
r   r8   r+   r   r   r]  r   r   r   r`  r   r   r   r   ;  s    z%CmfProject._create_sdesk_request_typec                 C   s   d| j  d| j d| j S r   )Z	ui_moduleZui_namer   r   r   r   r   hrefO  s    zCmfProject.href)NNN)NN)r$   N)N)N)N)NN)NNNNN)@__name__
__module____qualname__classmethodr   r   r    r<   rC   r[   r\   rU   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r  r  r   r  r;   r  r  r  r  r#  r7   r-  r.  r/  r1  r2  r6  r;  r<  r=  ru   rD  rE  rF  rG  rH  rK  rP  rR  rS  rV  rZ  r\  r   r   propertyra  __classcell__r   r   r   r   r	      s   r :& (


  ^
_
/.A



=


(-    
r	   c                   C   s
   t j S r   )r4   r	   r<  r   r   r   r   r   S  r   r   c                   C   s
   t j S r   )r4   r	   r=  r   r   r   r   r   T  r   )rY  r   r   r   r   r  r   Zcmf.includeZ"modules.project.fields.cmf_projectmodulesZcmf.utilr   r$   rG   Zcmf_projectr	   ZAPPZHOOK_CRON_DAILYrQ   r   r   r   r   <module>   s*               R