U
    d                     @   sx   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G dd dej	j
jjZejdd	  ejd
d	  dS )    )copy)datetimetimezone	timedelta)
monthrange)*Nc                       s"  e Zd Zedf fdd	Z fddZ fddZedd	d
dZdd ZedgddZ	edh fdd	Z
edddddddZediddZdd Zdd ZdjddZedd Zd d! Zdkd"d#Zeddd$ fd%d&
Zd'd( Zd)d* Zed+d, Zedl fd-d.	Zd/d0 Z fd1d2Zd3d4 Zd5d6 Zd7d8 Z fd9d:Zed;d< Zd=d> Z d?d@ Z!dAdB fdCdD
Z" fdEdFZ#dGdH Z$dIdJ Z%edKdL Z&edMdN Z'e(dOdPdQZ)dRd	dSdTZ*edUdV Z+dWdX Z,edYdZ Z-d[d\e.d] fd^d_Z/d`da Z0dbdc Z1e2ddde Z3  Z4S )m
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   s(  |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 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: Задача добавлена в проект, который установлен как "Проект/Раздел по-умолчанию" у пользователя, изменившего задачу - )is_newZlists
is_changedr)   ZresponsibleZdefault_projectloadload_fieldsZprimary_roleZstructural_projectmodelsr   getidZ
CmfCommentsavenamegZcurrent_personZ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	   r,   oldZis_default_listr2   newr)   r-   	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rA   ORtree_parent_idr'   r1   T)filtersfilter_projectrD   )	Exceptiondictvarsr/   r0   appendr1   valuer?   r-   _get_node_models
class_name_get_tree_dataZ_create_tree)r   Z	obj_modelZ
obj_filterrE   rD   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 )Nr>   rC   rD   r   r1   rE   )rH   rI   rM   rN   r0   r   get_tree_leaf)	r   rD   r"   rE   r   Zparent_filtrQ   rR   rS   r   r   r   rV      s      

zCmfProject.get_tree_leaf)rA   rE   r"   rF   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 )!Nr>   ordernor3   r!   	cmf_ownerr"   show_approved
show_tasksshow_archive
show_pfeed	show_disk	show_chat	show_epicshow_sprintshow_releaseshow_roadmapactivityZcmf_owner_assistantsZhas_tree_nodestree_hiddenZ	is_publicZsharelink_hashZperm_policy_anonymousZperm_policy_guestZperm_policy_sharelinkZperm_policyr   r   )r   rA   Zorder_bysys_type=r@   )	rH   r0   popr/   r   listrJ   CmfListZtree_fields)r   rA   rE   r"   rF   argsr   Zproject_filterZproject_fieldsrT   rR   rQ   rS   r   r   r   rO      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 )Nr>   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 )Nre   show_Tr^   )
r   
tree_nodesrL   rA   getattrre   remove
isinstancer/   CmfChatGroup)r#   noder   r   r   hide_project_parts  s"    


z5CmfProject._get_tree_root.<locals>.hide_project_partstagsc                 S   s   | j S r   r3   )rq   r   r   r   <lambda>&      z+CmfProject._get_tree_root.<locals>.<lambda>)key:r   rl   )rH   r0   r/   	CmfFolderrN   re   rl   rL   sortsplitr1   hasattrro   r   )r   rT   rD   rr   folderrP   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)   re   u   КорзинаT)r?   r3   re   systemrd   )r/   ry   r0   r2   )r   r   r   r   r   scaffold_trashcan5  s
    zCmfProject.scaffold_trashcanc                    s  d8dd}d}| j dkrd}|| tjtddt|| 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
 qX||tjtd ddd/d0td1| dd
 ||tjtd2d3d4td5| d6d7d
 d S )9Nc                    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   ).0kvir   r   	<genexpr>E  s     zNCmfProject.scaffold_backlog.<locals>.add_node_if_not_exists.<locals>.<genexpr>r?   )rl   ro   allitemsr2   rL   rK   )r?   
node_classnode_filter_kwargsnode_create_kwargsrq   r   r   r   add_node_if_not_exists>  s    
$
z;CmfProject.scaffold_backlog.<locals>.add_node_if_not_existsu   Задачиproject.agileZBacklogbacklog)re   順 )r3   filter_parentrW   )r?   r   r   r   rs   u   Тэгиrt   Zdatesu   Даты
   )r3   rW   r   ZfalseZnot_assigned)filter_responsible_setre   u   #НеНазначено)r3   r   Ztz   )monthdayhourminutesecondZmicrosecondc                    s   g | ]} j |d qS ))r   )replacer   r   Zstart_of_yearr   r   
<listcomp>  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_maxre   #Zno_alarm_date)r   Zfilter_plan_start_date_setZfilter_alarm_date_setre   u   #БезДатыFZnot_approved)Zfilter_approvedre   u   #Согласоватьu  В фильтр "#Согласовать" попадают все идеи, пожелания, задачи от пользователей.
Руководитель проекта обрабатывает список и переносит задачи в другие списки.
В идеале этот список должен быть обработан, то есть оставаться пустым к концу рабочего дня руководителя проекта.

примеры  списков, куда можно перенести задачи из "#Согласовать":
todo0 Срочно до мвп
todo1 В течение года
todo2 Через год
Отклонено
Версия октябрь 2021)r3   r   r*   )NNNN)logic_prefixr/   ry   rI   rl   ro   CmfActiveEntityFilter
filter_tagrc   Zcache_select_countrL   rn   r   nowr   utcr   rangezipr   )r   rj   r   r   Zfld_tasks_nameZ	fld_tasksZfld_tagsZ	fld_datesrq   r   Zstarts_of_monthsZends_of_monthsZmonth_rangesZmonth_namesZmonth_startZ	month_endr   r   r   scaffold_backlog<  s        


	
     

zCmfProject.scaffold_backlogc                 C   s   |s
| j }d| S N/rt   r   r3   r   r   r   project_dir  s    zCmfProject.project_dirc                 C   s   t jjj }|| S r   )r/   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   )r3   r   r   existsr   r   r   r   is_project_dir_exist  s    zCmfProject.is_project_dir_existr"   rE   c                   sB   t dd S t jf ||d|}|D ]}|  |  q(|S )Nr>   r   )rH   rI   r   get_full_treer   r   )r   r"   rE   rj   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	st 
 }t jjdd|_| |_d| j |_d|_|  || _	t j| ddd|_t j| ddd|_t j| dd| j d|d|_t j| | gd| j 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_|j ! D ]}	|	  qd'| _"d'| _#d'| _$d'| _%| jdd( | jd)kr\t j| d*d+d|_&t j
| |j&d,|d-|_'t j| d.d/d|_(t j|j(d0d1|d2|_)t j| d3d4d|_*t j|j*d5d6|d2|_+t j| d7d8d|_,t j-|j,d9dd:|_.t j| ddd|_t j|jdd|_/t j0| d;|d<|_1t jjd| jd|_t j| d=d|_2t j3|j2d>d|_4t j3|j2d?d|_5t j| d@d|_6d!|j_dA|j,_dB|j&_d"|j*_d#|j(_d$|j1_dC|j_d%|j2_d&|j6_dD|j_dE|j_dF|j_dG|j_d|j_d|j_d|j_|j ! D ]}	|	  qd| _7d| _8d| _9d| _:d| _;d| _<d| _#d'| _"d'| _$d'| _%| jdd( t j=j>j?}
|
D ],}t j=|
| |j6||j4dH|_@|j@  q.| jdIkrt jjd| jd|_t j| dJdd|_At j|jAdKd1|d1dL|_Bt j| ddd|_t j|jdd|_/t j| d=d|_2t j3|j2d>d|_4t j3|j2d?d|_5t j| d@d|_6d!|j_dA|jA_dB|j_d"|j_d#|j_d$|j2_dC|j6_d%|j_d&|j_d|j_d|j_|j ! D ]}	|	  qpd| _7d| _8d| _"d| _#d'| _$d'| _%| jdd( t j=j>j?}
|
D ],}t j=|
| |j6||j4dH|_@|j@  qdS )MuU    Добавляем структуру папок в новый проект
        zlist.pfeed:defaultcodeztask.epic:defaultzlist.agile_sprint:defaultzlist.release:defaultzlist.base:defaultuc   Вызываем разворачивание чтобы появилась папка задачиr   )make_dataclassZ	DataEmptyztask.gantt_project:defaultu	   Гант Tu   Дискdisk)r?   r3   re   u
   Архивarchiveu
   Лентаu   Лента проекта pfeed)r?   r3   r*   	list_typer   u   Чат )r?   r&   r3   zproject.wikir   )re   rD   u   Документ1)r?   r3   u   ДокументыNu   Документ2r   i i" iI i i  Fr7   r   ZEpicsepiczEpic 1)r)   r?   r3   r   ZSprintssprintzSprint 1Zkanban)r?   r3   r   r   ZReleasesreleaseu   Релиз 1rh   ZRoadmapsroadmapu   Roadmap Проекта)r?   r3   r   u   Доска Канбан)r?   r3   r   u   Фильтрыu   Фильтр 1u   Фильтр 2u   Отчетыi i i q i0 i@ iP4 i`[ )r3   r?   report_typeZreport_filterzproject.baseu   В работеu   Канбан1)r?   r3   r   r   Zui_view_form)Cr/   ZCmfLogicTyper0   ZlogginginfoZdataclassesr   r   r   Zmain_gantt_projectCmfTaskr   r)   r3   r   r2   ry   r   r   ri   r   rp   chatr   r1   r   CmfDocumentZdoc1ZdocsZ
docs__doc2rW   rd   __dict__valuesr]   r[   r\   r^   ZepicsZepics__epic1ZsprintsZsprints__sprint1ZreleasesZreleases__release1ZroadmapsZ
CmfRoadmapZroadmaps__roadmap1Z
docs__doc1ZCmfKanbanBoardZkanban_boardrE   ZCmfTaskFilterZfilters__filter1Zfilters__filter2ZreportsrZ   rY   rb   r_   ra   r`   ZCmfTaskReportr   choicesZreports__report1Zin_workZin_work__kanban1)r   Zlt_pfeedZlt_epicZ	lt_sprintZ
lt_releaseZlt_baser   tZgantt_projectr   r   itemr   r   r   scaffold  sB   
              
 
 zCmfProject.scaffoldc                 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 )Nr3   rf   r1   r   r$   u   Проект с именем uA    уже существует. Укажите другое имя.Tr8   u-   Раздел на диске с именем uF    уже занят. Укажите другое имя проекта.)r/   r   Zslistr3   r1   r<   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 )	NrC   r3   r   r   r$   u7    с таким именем уже существуетTr8   )rK   r0   r<   Zverbose_name)r   r3   r   Z
prj_filterr   r   r   _check_unique  s
    zCmfProject._check_uniquec                    s$   |  || t j|||d|S )N)r3   r   )r   r   r   )r   r3   r   rj   r   r   r   r   r     s    zCmfProject.createc                 C   sF  ddddddddd	d
dg}ddg}|D ]}d| }| j | jr&|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}|rD| j | j |_|jdd qDtj	jdd| jgddd| ggd}|r&| j | j |_|jdd q&| j
jrBt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   ry   r   rk   r
   r   re   r$   r   Tr7   r   zlist.rD   rf   )r   r,   rJ   r/   r0   r1   rL   rd   r2   ri   r^   rp   )r   Z	sys_typesZnode_modelsre   Z	fieldnameZ	nodeclassZsysnoder   r   r   _calc_hidden_nodes  sJ    

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   r5   r   r   r   r   r5     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)   r,   r?   r<   r"   r
   rD   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*   r,   r/   r   Zconfluence_convertrL   r1   r   r   r   r   
_calc_text  s    zCmfProject._calc_textc                 C   s   |    d S r   )Z_check_simple_permr   r   r   r   check_simple_perm  s    zCmfProject.check_simple_permc           
         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 d}| jjr| jstd |   | jjr| | jjr| | 	| jj}|| 	  | j r| js| j| _d}| j s|   | jstjjdd| _|   |   t j||}| j sF| jjrPtj  |r^|   tjjddddggdgd}|D ]}	d|	_|	jdd q~|S )Nr3   r   r1   r   r$   u   Проект u    уже существуетTr8   r   _z%Y-%m-%d-%H%M%SFu<   Имя проекта не может быть пустым.zsystem:defaultr   onboarding_statuszNOT INr   cancelr@   r7   )r+   r/   r   r0   r3   r1   r<   r   r   r   r   renamer   r   r,   r   r:   r   r   r   CmfProjectPermSchemer   r=   r   r2   Ztrigger_reloadr   Z
CmfLicenserh   r   )
r   rj   r   r   Zproject_dir_rfileZshould_be_scaffoldedZ	old_rfileresultZonboardingsZ
onboardingr   r   r   r2     sH    "
zCmfProject.savec                 C   s   t t|dd }|j|dgd}|o:t t|dd }|oN|j|dgd}|r\|jjp^d}|ovt t|dd }	|	o|	j|dgd}
|
r|
jjpd}|  |r|r|t|| d  |_n|r|d |_n|r|d |_|jdd d S )	Nrx   r   rW   )r1   rA   r(   i  Tr7   )	rm   r/   r{   r0   rW   rL   Zcheck_owner_permsintr2   )r   Zitem_idZ	anchor_idZnext_idZ
item_modelr   Zanchor_modelZanchorZanchor_ordernoZ
next_modelZ	next_itemZnext_ordernor   r   r   	move_itemH  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_prefixd  s    zCmfProject.get_code_prefixT)	recursivec                   sD   | j j}t j|d|i|}| |r@tj|}|r@|  |S )Nr   )	r3   rL   r   deleter   r/   r   r0   Zmove_to_trash)r   r   rj   r   Zcur_namer   r   r   r   r   r   h  s    
zCmfProject.deletec                    s(   t  jf |}tj| jj|   |S r   )r   restorer/   r   Zrestore_from_trashr3   rL   r   )r   r   r   r   r   r   r   r  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   r@   )	r   r   r   r   r   r/   r   rh   r1   )r   r   r   r   r   r   _list_tasks_need_to_startw  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_idr3   rP   msgpriority)auto_alarm_dater   printrX   r3   rL   r/   Z	CmfNotifyZplace_notifyr1   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)r   )r/   r   rh   r   r   r   r2   )r   r#   r   r    r   r   r   _cron_auto_alarm_date  s
    z CmfProject._cron_auto_alarm_datec                 C   s    | j dgdD ]}|  qd S )Nz**rB   )rh   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   )r1   rL   )r   tagr   r   r   
<dictcomp>  s      z5CmfProject.hook_task_tags_changed.<locals>.<dictcomp>r   )r
   re   rs   c                 S   s   i | ]}|j j|qS r   )r3   rL   )r   r}   r   r   r   r     s    rG   filter_tag_idrD   r
   r   re   r   )rA   r   )r)   r?   r3   z: Create new filter for z with category r   )r?   r3   re   r   r   )r/   ry   r0   r1   rh   r   r   rL   rg   Ztag_categoryr-   r3   r2   rD   r   r4   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_changed  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   rj   r   r   r   r   public_list  s    zCmfProject.public_listr   )	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_childrenr?   notify_all_personsrX   cmf_owner_assistantr  )	setr.   r  unionZall_relation_personsrX   r	  r   get_all_followers)r   r  rj   r   r   r   r   r   r    s       zCmfProject.get_all_followersc                 O   s   t jj| f||S r   )r/   r   check_project_role_access)r   rj   r   r   r   r   r    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)r,   zPPP-PR-ADMIN)rP   )r+   r,   keysZproject_perm_allow_fieldsrn   r  )r   Zchanged_fieldsZallowed_fieldr   r   r   _check_project_perm
  s    zCmfProject._check_project_permc                 C   s   d| j  d| j d| j S r   )Z	ui_moduleZui_namer   r   r   r   r   href  s    zCmfProject.href)NNN)NN)r#   N)N)N)N)NN)5__name__
__module____qualname__classmethodr   r   r   r6   r=   rU   rV   rO   r~   r   r   r   staticmethodr   r   r   r   r   r   r   r   r   r5   r   r   r   r2   r   r   r   r   r   r   r   r   r   rh   r  r  r  r  r  r
  r  r  r  propertyr  __classcell__r   r   r   r   r   
   s|   r :& '


 5
)2



=

r   c                   C   s
   t j S r   )r/   r   r   r   r   r   r   ru      rv   ru   c                   C   s
   t j S r   )r/   r   r   r   r   r   r   ru   !  rv   )r   r   r   r   Zcalendarr   Zcmf.includeZ"modules.project.fields.cmf_projectmodulesr#   rA   Zcmf_projectr   ZAPPZHOOK_CRON_DAILYrK   r   r   r   r   <module>   s           