U
    [SeR                    @   s   d dl m Z  d dlmZmZmZ d dlmZ d dl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 )    )copy)datetimetimezone	timedelta)
monthrangeN)*)cmfutilc                       s  e Zd Zedx fdd	Z fddZ fddZdd	 Zedyd
dZedz fdd	Z	edddddddZ
ed{ddZdd Zdd Zdd Zd|ddZedd Zdd Zd}d d!Zeddd" fd#d$
Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zed/d0 Zed~ fd1d2	Zd3d4 Z fd5d6Zd7d8 Zd9d: Zed;d< Z d=d> Z!d?d@ Z"dAdB Z# fdCdDZ$ fdEdFZ%eddGdHZ&dIdJ Z'dKdL Z(dMdNdO fdPdQ
Z) fdRdSZ*dTdU Z+dVdW Z,edXdY Z-edZd[ Z.e/d\d]d^Z0ed_d` Z1dadb Z2edcdd Z3ededf Z4dgdh Z5didj Z6dkdl Z7ddmdnZ8e9dodp Z: fdqdrZ;ddsdtZ<ddddNdNdudvdw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_wfc                 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	only_datauc   Нельзя указать Спипок по-умолчанию из другого проектаabort)	r
   
is_changedoldZis_default_listsavenewparentload	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r0   ORtree_parent_idINidT)filtersfilter_projectr3   )	Exceptiondictvarsmodelsgetappendr5   valuer.   r*   _get_node_models
class_name_get_tree_dataZ_create_tree)r   Z	obj_modelZ
obj_filterr6   r3   r   objr)   Z
parents_idZparent_filtermodel
model_namemodel_filter	tree_datar   r   r   get_obj_tree0   s*      

zCmfProject.get_obj_treeprojectc           	         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-   r2   r3   r   r5   r6   )r9   r:   r@   rA   r=   r   get_tree_leaf)	r   r3   project_typer6   r   Zparent_filtrD   rE   rF   r   r   r   rJ   Q   s      

zCmfProject.get_tree_leaf)r0   r6   rK   r7   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-   ordernonamecmf_owner_id	cmf_ownerrK   show_approved
show_tasksshow_archive
show_pfeed	show_disk	show_chat	show_epicshow_sprintshow_releaseshow_roadmapactivitycmf_owner_assistantshas_tree_nodestree_hidden	is_publicsharelink_hashperm_policy_anonymousperm_policy_guestperm_policy_sharelinkperm_policyr   r	   )r   r0   Zorder_bysys_type=r/   )	r9   r=   popr<   r	   listr;   CmfListZtree_fields)r   r0   r6   rK   r7   argsr   Zproject_filterZproject_fieldsrG   rE   rD   rF   r   r   r   rB   c   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 )Nrd   show_TrU   )
r   
tree_nodesr?   r0   getattrrd   remove
isinstancer<   CmfChatGroup)rI   noder   r   r   hide_project_parts   s"    


z5CmfProject._get_tree_root.<locals>.hide_project_partstagsc                 S   s   | j S r   rM   )rp   r   r   r   <lambda>       z+CmfProject._get_tree_root.<locals>.<lambda>)key:r   rk   )r9   r=   r<   	CmfFolderrA   rd   rk   r?   sortsplitr5   hasattrrn   r	   )r   rG   r3   rq   folderrC   rI   r   r   r   _get_tree_root   s$     



zCmfProject._get_tree_rootc                 C   s8   t jj| dd}|s4t j| ddddd}|jdd |S )Ntrashcan)r)   rd   u   КорзинаT)r.   rM   rd   systemr]   Fnotify)r<   rx   r=   r'   )r   r~   r   r   r   scaffold_trashcan   s
    zCmfProject.scaffold_trashcanc                 C   s@   d}t j| |d}|jdd t j| d|dd}|jdd |S )NzX[lists, EXISTS, [[cache_status_type = IN_PROGRESS], [logic_prefix = list.agile_sprint]]]r)   ft_add_ubqlFr   u   Активные спринтыT)r.   rM   Zkanban_filterr   )r<   CmfTaskFilterr'   CmfKanbanBoard)r   r   Zactive_sprints_filterZactive_sprints_boardr   r   r   scaffold_active_sprints   s    z"CmfProject.scaffold_active_sprintsc                    s  d;dd}d}| j dkrd}tj| d}|jd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||d0d1td2||j  | dd qt||tjtd ddd3d4td5| dd ||tjtdd6d7td8| d9d:d d S )<Nc                    sj   | j D ]0 t |rt fdd| D r   S q|f d| i||}|jdd | j j| |S )Nc                 3   s   | ]\}} | |kV  qd S r   r   ).0kvir   r   	<genexpr>   s     zNCmfProject.scaffold_backlog.<locals>.add_node_if_not_exists.<locals>.<genexpr>r.   Fr   )rk   rn   allitemsr'   r?   r>   )r.   
node_classnode_filter_kwargsnode_create_kwargsrp   r   r   r   add_node_if_not_exists   s    
$
z;CmfProject.scaffold_backlog.<locals>.add_node_if_not_existsu   Задачиproject.agileZBacklogr)   Fr   backlog)rd   順 T)rM   filter_parent
tmp_filterrL   r   )r.   r   r   r   rr   u   Тэгиrs   Zdatesu   Даты
   )rM   rL   r   ZfalseZnot_assigned)filter_responsible_setrd   u   #НеНазначено)rM   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>6  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   7  s   u   Январьu   Февральu   Мартu   Апрельu   Майu   Июньu   Июльu   Августu   Сентябрьu   Октябрьu   Ноябрьu   Декабрь)r                        	   r         date)Zfilter_plan_start_date_minZfilter_plan_start_date_maxrd   #Zno_alarm_date)r   Zfilter_plan_start_date_setZfilter_alarm_date_setrd   u   #БезДатыZnot_approved)Zfilter_approvedrd   u   #Согласоватьu  В фильтр "#Согласовать" попадают все идеи, пожелания, задачи от пользователей.
Владелец проекта обрабатывает список и переносит задачи в другие списки.
В идеале этот список должен быть обработан, то есть оставаться пустым к концу рабочего дня владельца проекта.

примеры  списков, куда можно перенести задачи из "#Согласовать":
todo0 Срочно до мвп
todo1 В течение года
todo2 Через год
Отклонено
Версия октябрь 2021)rM   r   text)NNNN)logic_prefixr<   r   r'   rx   r:   rk   rn   CmfActiveEntityFilter
filter_tagrZ   Zcache_select_countr?   rm   r   nowr   utcr   rangezipr   )r   ri   r   r   Zfld_tasks_namebacklog_filterZ	fld_tasksZfld_tagsZ	fld_datesrp   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/rs   r   rM   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   )rM   r   r   existsr   r   r   r   is_project_dir_exist  s    zCmfProject.is_project_dir_existrK   r6   c                   sB   t dd S t jf ||d|}|D ]}|  |  q(|S )Nr-   r   )r9   r:   r   get_full_treer   r   )r   rK   r6   ri   r   resrI   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|_|jd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r4t 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 ]}	|	jdd qd| _#d| _$d| _%d| _&| jddd, | jd-krt j| d.d/dd|_'t j
| |j'd0|d1|_(t j| d2d3dd|_)t j|j)d4d5|d6|_*t j| d7d8dd|_+t j|j+d9d:|d6|_,t j| d;d<dd|_-t j.|j-d=dd>|_/t j| d!d"| j0d?|_t j|jd| j0d@|_1| 2 |_3t jjd| jd|_t j4dAdB| dC|_5t j| dDdEdd|_6t j4|j6dFd |_7t j4|j6dGd |_8t j| dHdIdd|_9t j| dJdKdd|_:d%|j_dL|j-_dM|j'_d&|j+_d'|j)_d(|j3_dN|j_d)|j5_d*|j6_dO|j9_dP|j_dQ|j_dR|j_dS|j_dT|j:_d+|j_d|j_ d|j_ d|j_ d|j_ |j!" D ]}	|	jdd qLd| _;d| _<d| _=d| _>d| _?d| _@d| _$d| _#d| _%d| _&d| _Ad| _Bd| _C| jddd, t jDjEjF}
|
D ]B}t jD|
| |j9||j7dU|_G|dVkrd|jG_|jGjdd q| jdWkrt jjd| jd|_t j| dXd"d#|_Ht j|jHdYd5|d5dZ|_It j| d!d"d#|_t j|jdd |_1t j| dDdEdd|_6t j4|j6dFd |_7t j4|j6dGd |_8t j| dHdIdd|_9d%|j_dL|jH_dM|j_d&|j_d'|j_d(|j6_dN|j9_d)|j_d*|j_d+|j_d|j_ d|j_ d|j_ |j!" D ]}	|	jdd q:d| _;d| _<d| _#d| _$d| _%d| _&d| _Ad| _B| jddd, t jDjEjF}
|
D ]0}t jD|
| |j9||j7dU|_G|jGjdd q| jdk
rzt jJjd[d| _K| Ld\d]}| Ld^d_}| Ld`da}dbdcddt jjdeddf|||dgdhdit jjdeddf|||dgdjdkt jjdlddm|||dgdndot jjdlddm|||dggdpdqdhdit jjdeddf|||dgdrdst jjdeddf|||dggdpg}| M| | jNdtdut jjdvd|dfdw t j| dxdydd|_Ot j4dz| d{|_Pt jQ|jO| |jPd|d}|_Rt j4| d~d|_St jQ|jO| |jSdd}|_Tt j4| dd|_Ut jQ|jO| |jUdd}|_Vt j| ddddd|_Wt j|jWddd#|_Xt j|jWdd |_Yt j| dHdIdd|_9t j| dDdEdd|_6t j4|j6dFd |_7t j4|j6dGd |_8t j| dddd|_Zt j| dddd|_[d%|jO_dL|jW_dM|jZ_d&|j[_d'|j6_d(|j9_dN|j_d)|j_d*|j_dO|j_d|j_ d|j_ d|j_ d|j_ d|j_ |j!" D ]}	|	jdd 	qd| _;d| _<d| _#d| _$d| _%d| _&d| _\d| _]d| _^d| __d| _`d| _Ad| _B| jddd, t jDjEjF}
|
D ]<}|ad
r,t jD|
| |j9||j7dU|_G|jGjdd 
q,| b  | c  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:default	   Гант TFr   u   Дискdisk)r.   rM   rd   r   u
   Архивarchiveu
   Лентаu   Лента проекта pfeed)r.   rM   r   	list_typer   r   u   Чат )r.   	executorsrM   r   zproject.wikir   )rd   r3   u   Документ1)r.   rM   u   ДокументыN)r.   rM   rd   u   Документ2r   i i" iI i i  i r"   r   r   ZEpicsepiczEpic 1)r)   r.   rM   r   ZSprintssprintzSprint 1Zkanban)r.   rM   r   r   ZReleasesreleaseu   Релиз 1rg   ZRoadmapsroadmapu   Roadmap Проекта)r.   rM   r   )r.   rM   rd   workflow)r.   rM   r   u   Все задачиfilter_all_tasks)rM   rd   r.   u   Фильтрыr6   u   Фильтр 1u   Фильтр 2u   Отчетыreportsu   Компоненты
componentsi i i q i0 i@ iP4 i`[ ip i )rM   r.   report_typeZreport_filterZagile_sprintzproject.baseu   В работеu   Канбан1)r.   rM   r   r   Zui_view_formzsystem:servicedeskz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)rM   r   r   categoryui_form_viewui_form_createui_form_view_inneru9   Запросить новую учетную записьuP   Запросите новую учетную запись для системы.u7   Сообщить о системной проблемеu   Дайте нам знать, если что-то не работает должным образом, и постарайтесь быстро восстановить его работоспособность.ztask.sd_incident:defaultZ	incidentsu?   Сообщить о сломанном оборудованииu   Сообщите об оборудовании, которое может быть неисправным или сломанным, например разбитый экран компьютера или поврежденный сервер.)rM   typesu+   Логины и учетные записиu<   Запросить доступ администратораuY   Например, если вам нужно администрировать EvaProject.u3   Запрос по электронной почтеuu   Запрос получен от вашего канала поддержки по электронной почте.ztask.sd_emailed_request:default)rM   r   r   r   r   u   Очередиqueuez[cache_status_type != CLOSED])r   r)   u   Все обращения)r.   r)   Ztask_filterrM   z?[responsible = __G_CURRENT_USER], [cache_status_type != CLOSED]r   u   Назначенные мнеz[cache_status_type = CLOSED]u#   Закрытые обращенияu   База знанийknowlage_basereadonly)r.   rM   rd   ra   r   u   КатегорииZknowlage_base_categoriesu   Статьиu   Каналыservicedesk_channelsu   Клиентыservicedesk_clientsZanalysis)dr<   CmfLogicTyper=   ZlogginginfoZdataclassesr   r   r   main_gantt_projectCmfTaskr   r)   rM   r   r'   rx   r   r   rh   r   ro   chatr   r~   r5   r   CmfDocumentZdoc1ZdocsZ
docs__doc2rL   r]   __dict__valuesrT   rR   rS   rU   ZepicsZepics__epic1ZsprintsZsprints__sprint1ZreleasesZreleases__release1ZroadmapsZ
CmfRoadmapZroadmaps__roadmap1r   Z
docs__doc1r   Zkanban_boardr   r   r6   Zfilters__filter1Zfilters__filter2r   r   rQ   rP   rY   rV   rX   rW   Zshow_filtersZshow_reportsZshow_componentsZCmfTaskReportr   choicesZreports__report1Zin_workZin_work__kanban1CmfProjectNotifySchemenotify_scheme_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_clients
startswith_create_assign_to_project_create_sdesk_sla)r   Zlt_pfeedZlt_epicZ	lt_sprintZ
lt_releaseZlt_baser   t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   sj   t jj|dgd}|s(td| dd t  }| j d| j d| |_|j|_d|_|jddd	 |S )
Nui_form_json)r   r0   u3   Отсутствует экранная форма Tr#   z: r   Fr   )	r<   Z	CmfUiFormr=   r+   task_code_prefixrM   r  Zcmf_model_namer'   )r   r   action_nameZui_formZ_ui_formr   r   r   r     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 )Nzsdesk-client:defaultr   zsdesk-agent:defaultTr!   )r<   CmfProjectRoler=   CmfProjectRoleAssignr)   Zproject_rolemembersr>   gcurrent_userr'   )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)   rM   Zwidget_typeTr!        z+request_type.request_category = 'incidents')r)   rL   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)r<   CmfCalendarr=   ZCmfSDeskSlar'   ZCmfSDeskSlaGoalZCmfSDeskSlaTrigger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 )NrM   re   r5   r   r   u   Проект с именем uA    уже существует. Укажите другое имя.Tr#   u-   Раздел на диске с именем uF    уже занят. Укажите другое имя проекта.)r<   r	   slistrM   r5   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 )	Nr2   rM   r   r   r  u7    с таким именем уже существуетTr#   )r>   r=   r+   Zverbose_name)r   rM   r   Z
prj_filterr   r   r   _check_unique  s
    zCmfProject._check_uniquec                    s$   |  || t j|||d|S )N)rM   r   )r  r   r   )r   rM   r   ri   r   r   r   r   r     s    zCmfProject.createc                 C   sZ  d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r4|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}|rR| j | j |_|jdd qRtj	jdd| jgddd| ggd}|r4| j | j |_|jdd q4| j
jrVtjjdd | jgd}|rV| j
j |_|jdd d S )!NtasksZapprovedr   r   r   r   r   r   r   r   r~   r   r   r6   r   r   r   r   rx   r   rj   r   r   rd   r  r   Tr!   r   zlist.r3   re   )r   r%   r;   r<   r=   r5   r?   r]   r'   rh   rU   ro   )r   Z	sys_typesZnode_modelsrd   Z	fieldnameZ	nodeclassZsysnoder   r   r   _calc_hidden_nodes  sZ    

zCmfProject._calc_hidden_nodesc                    s"   t   dd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_schemer   r  )r   save_preload_fieldsr   r   r   r   r    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<   Нельзя менять родителя у проектаsectionzCmfWiki:ClassrI   zCmfProject:Class)r)   r%   r.   r+   rK   r   r3   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_convertr?   r5   r   r   r   r   
_calc_text  s    zCmfProject._calc_textc                    s   dd l | sdS t| } dd|  }|d}d t|dkr\ddd |D  n|d d d  tj	j
d	d
gd
d   dgd}tdd |D }t|}  |krt fdd|D dd}|r tt|d 7  n d7    S )Nr   r  z\W+-r   c                 S   s   g | ]}|d  qS )r   r   )r   chunkr   r   r   r     s     z3CmfProject.get_prefix_from_name.<locals>.<listcomp>r   z--r  ZILIKE%r0   r   c                 S   s   g | ]}|j  qS r   )r  lower)r   rI   r   r   r   r     s     c              
      s8   g | ]0}|   rd d|   dqS )z\Dr  )r   r&  subr   )r   pprefixrer   r   r     s      )default1)r+  r   Ztranslit_stripr'  r&  rz   lenjoinr<   r	   r  setrg   maxstrintupper)rM   ZslugchunksZprojectsprefixesZexisting_prefixesZmax_prefix_numr   r)  r   get_prefix_from_name  s,    

zCmfProject.get_prefix_from_namec                 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#   r5   r   r  re   rM   )r   r0   include_deletedu   Код u2    уже используется проектом u   . Выберите другойr   ZLIKEz-%rI   zproject.nameu8    ранее использовался проектом u   . Это может привести к пропускам в нумерации кодов. Если это нежелательно - укажите другой префиксur   Запущен фоновый процесс смены префиксов кодов у задач проекта)ri   )r  r%   Ztask_code_use_logic_type_prefixr?   r4  Zcode_prefixr+   r<   r	   r=   r5   rM   CmfTaskCodeHistoryrI   is_newZcmf_deferred_taskr   Zrecalculate_codes_celery)r   Zproject_with_prefixZ	code_usedr   r   r   _calc_task_code_prefix  sF    

z!CmfProject._calc_task_code_prefixc                 C   s   |    d S r   )Z_check_simple_permr   r   r   r   check_simple_perm=  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   )translitr8  ruT)Zlanguage_codereversedc                 S   s   g | ]}|r|qS r   r   r   cr   r   r   r   I  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   rB  r   r   r   r   M  s     z@CmfProject._calc_task_code_prefix_for_section.<locals>.<genexpr>ZWIKIr  re   r5   r   r  )Ztransliterater?  rM   r*   r?   r+  findallr.  r/  r4  r<   r	   sgetr5   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 rHtjjsHtjsHtjsHtjjdddgd}|j	j
tjkrHtddd | j rtjjdd| jgd	d
| j	ggd}|rt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rX| jstd |   | jjrX| | jjrX| | | jj}||   | j rt| jsp| j| _d}| j s|   | js| j dkrtj!jdd| _ntj!jdd| _| j"stj#jdd| _"| j$stj%jdd}|stj%jdd}|| _$| &  | '  | j(s<| j)dkr0| *  ntddd | +  t, j-||}	| j sn| jjsn| j.jrxtj!/  |ddrd}|r| 0  | j s| j"jrtj#/  tj1j2ddddggdgd}
|
D ]}d|_3|j-dd q|	S ) Nr   r   ZProjectAdminsr  u   Для создания проектов попросите Администратора системы добавить Вас в группу Администраторы проектовTr#   rM   r5   r      Проект     уже существуетr   _%Y-%m-%d-%H%M%SF<   Имя проекта не может быть пустым.r   servicedesk:defaultr   system:default)Z
is_defaultr  u8   Укажите Префикс для кода задачdont_scaffoldonboarding_statusNOT INr   cancelr/   r!   )4r<  r
  r  Zis_adminZdisable_permissionsZacl_admin_moder<   CmfPersonGroupr=   r5   r?   Zcurrent_person__member_ofr+   r	   rM   r   r   r   r   renamer   r   document_header_textr%   r   
clean_textdocument_footer_textr  r&   r   r  r  r   CmfProjectPermSchemer   r   r  r  r!  r,   r  rK   rF  r=  r   r'   Zservicedesk_publicZtrigger_reloadr  
CmfLicenserg   rO  )r   ri   r   Zproject_admins_groupr   project_dir_rfileshould_be_scaffolded	old_rfiler  resultonboardings
onboardingr   r   r   r'   X  s    "



zCmfProject.savec           
         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stjjdd| _|   |   | js| j dkr| !  n| "| jj| _| #  t$ j%||}|r| &  tj'j(ddddggdgd}|D ]}	d|	_)|	j*dd q
|S )NrM   r   r5   r   r  rG  rH  Tr#   r   rI  rJ  FrK  r   rL  r   rM  r  rO  rP  r   rQ  r/   r!   )+r<  r<   r	   r=   rM   r5   r+   r   r   r   r   rS  r   r   rT  r%   r   rU  r?   rV  r  r&   r   r  r  r   rW  r   r   r!  r,   r  rK   rF  r7  r=  r   _save_importr  rX  rg   rO  r'   )
r   ri   r   r   rY  rZ  r[  r\  r]  r^  r   r   r   r_    s^    "

zCmfProject._save_importc                 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 )Nrw   r   rL   zparent.disable_simple_permr5   r0   Tr	   Fr   r  r!   )rl   r<   rz   r=   rL   r?   r)   rA   Zdisable_simple_permZcheck_owner_permsr3  r'   )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_prefixTF)	recursiveTEXKOM_db_deletec                   s<  | j j}|rd | _| jdd dD ]f}tt| jdd| gdddD ]B}td|  tt| j	|j
dddrD|jddd	 t  qDq"tjj| ddd
D ]"}td|  |jddd	 qtjj| ddd
D ]"}	td|	  |	jddd	 qt j|||ddd|}
| |r8tj|}|r8|  |
S )NTr!   )CmfComponentro   r  CmfAttachmentZCmfImportDownloadr   rh   ZCmfTransZ	CmfStatusZCmfWorkflowZCmfSchemeWfr  r  r   Z	CmfPersonrR  r   r   rx   r)   r   )r   r:  include_systemu   Удаляем )r5   r:  rh  )re  force)rI   r:  rh  F)rd  re  rh  r   )rM   r?   r   r'   r;   r<   rg   r
  debugrE  r5   deleteZcommit_with_eventZCmfGanttTaskr;  r   r   r   r=   Zmove_to_trash)r   rd  re  ri   r   Zcur_nameZcls_namerowZ
gantt_taskZ	task_coder   r   r   r   r   rk    s6    "
 zCmfProject.deletec                    s(   t  jf |}tj| jj|   |S r   )r   restorer<   r   Zrestore_from_trashrM   r?   r   )r   r   r   r   r   r   rm  5  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   rg   r5   )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d| d| j d| j j	 ddd d S )Nu&   Отправляем карточку u   Рекомендацияu   
            В проекте u(   есть задачи с планом, но без будильника.
            Назначьте будильник, или список с планом,
            чтобы задачи появились у исполнителя в ленте.
            (сброшен флаг "z")
            r   )ZpersonrM   rC   msgpriority)
auto_alarm_daterq  printrO   rM   r?   r<   Z	CmfNotifyZplace_notifyZcaption)r   r  r   r   r   '_notify_project_owner_not_planned_tasksK  s"    z2CmfProject._notify_project_owner_not_planned_tasksc                 C   s:   t jjddD ]&}| }|D ]}|j|_|  qqd S )NT)rt  )r<   r	   rg   rq  rn  rp  r'   )r   rI   r  taskr   r   r   _cron_auto_alarm_datec  s
    z CmfProject._cron_auto_alarm_datec                 C   s    | j dgdD ]}|  qd S )Nz**r1   )rg   rv  )r   rI   r   r   r   &notify_project_owner_not_planned_tasksl  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d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   )r5   r?   )r   tagr   r   r   
<dictcomp>z  s      z5CmfProject.hook_task_tags_changed.<locals>.<dictcomp>r   )r   rd   rr   c                 S   s   i | ]}|j j|qS r   )rM   r?   )r   r|   r   r   r   r|    s    r8   filter_tag_idr3   r   r   rd   r{  r%  )r)   r.   rM   z: Create new filter for z with category Fr   r   )r.   rM   rd   r   r   )r<   rx   r=   r5   rg   r   r}  r?   rf   Ztag_categoryr*   rM   r'   r3   r   r
  rj  )
r   rz  Ztask_tags_id_dictZtasks_filterZtags_folderZcategory_foldersZ	ae_filterr{  Zcategory_folderZtag_idr   r   r   hook_task_tags_changedq  sz    
  


   
  
 
   z!CmfProject.hook_task_tags_changedc                 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   ri   r   r   r   r   public_list  s    zCmfProject.public_listc                 O   s|   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||}|sTd S z|  W n tk
rv   Y d S X |S )Nr5   rM   r   rN   r[   Zactivity_idr   r   zworkflow.namerO   cmf_created_atrK   r  descriptionr^   r_   r`   ra   rb   rc   r   Zpublic_html_schemerT  rV  r0   )r<   r	   r=   Z_acl_check_readZCmfPermissionError)r   ri   r   Zfields_to_returnrI   r   r   r   
public_get  sF    zCmfProject.public_getc                 O   s   t jj| f||S r   )r<   rW  check_project_role_access)r   ri   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)rC   )r<  r%   keysZproject_perm_allow_fieldsrm   r  )r   Zchanged_fieldsZallowed_fieldr   r   r   _check_project_perm  s    zCmfProject._check_project_permc                 C   s   |D ]~}t  }| |_|d|_|jdd |dD ]H}| j|d|d|d|d||d|d	|d
d q8qd S )NrM   Fr   r   r   r   r   r   r   r   )rM   r   r   r   groupr   r   r   )r<   ZCmfSDeskRequestGroupr)   r=   rM   r'   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!   )r<   ZCmfSDeskRequestTyper)   rM   r   r   r   r   r   Zrequest_categoryr  r>   r'   )
r   rM   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   href"  s    zCmfProject.hrefc                    sD   ddl m} t  }t|dkr@|d d  d||d }|S )Nr   )cmf_hashlib      r"  r   )cmf.utilr  r   gen_coder.  Zshort_str_enc)r   r  Zres_coder   r   r   r  &  s
    
zCmfProject.gen_codec                 K   s   |s| j d }tj|d}d}| jddD ]8}|j|ks*|jds*|jdrRq*t||j|j q*|	 D ]\}}||j
krlt||| ql|S )N    Копияrs   )%attachmentsZchat_groupsZcmf_archivedr  Zcmf_deletedZ
cmf_importZcmf_locked_atZcmf_locked_byZcmf_modified_atZcmf_modified_byZcmf_viewed_atr   Zcommentsr
   Z	documentsZext_idZfavorite_forr\   r5   Zimport_originalZimport_raw_jsonZlocal_linksZlocal_links_docs_inZlocal_links_tasks_inrM   r_   r   statusZstatus_closed_atZstatus_in_progress_endZstatus_in_progress_startZstatus_modified_atZstatus_review_atr  r  rk   Ztask_filtersT)Z
is_definedZ_idZperm_)rM   r<   r	   r   rA   endswithr   setattrr?   r   r0   )r   rM   r   new_projectZskip_fieldsZfieldattrr?   r   r   r   clone.  s    
	

zCmfProject.clone)rM   r   r  structure_copy	full_copyc                   s   fdd fdd}dd  |r(d}t jj| jdgd	}	|	j|pL|	jd
 ||| d}
|
jdd|d |r|
|
t|	jd |r||
|	d |	j	rt j
j|
|	j	jd|
_	|
jdddd |
S )Nc                    s   |D ]}t |tjtjtjfr q|dg |j|jdd}||_| |_	| |_
|  |  |  |  |  t|dddkrtj| d}|jddd ||_|jdddd	  | |t|j qd S )
Nrk   T)rM   Zcopy_attachmentsrd   Fr   r   )r   emit)Znoitfyr  r"   )rn   r<   r   r   ro   load_fieldsr   rM   r.   r)   root_parent_calc_perm_parent_calc_perm_inherit_acl_id_calc_perm_has_acl_calc_perm_acl_calc_perm_effective_aclrl   r   r'   r   rg   rk   )r  
new_parentorig_childrenZ
orig_child	new_childr   )_copy_tree_nodesr   r   r  K  s&    z9CmfProject.create_from_template.<locals>._copy_tree_nodesc              
      s  dd t jj| ddD }|dd t jj| ddD  |j }|dg  || }d| j |_d |_	|j
ddd	 |  |j
ddd	 || _| j
ddd	 t jj|dd
ddddd
dgd}i }g }|D ]^}||krq҈ || d}	|j|j|j|jd}
|
 D ]Z\}}|D ]J}|j|kr,qt|	|| t|	|||j d|jj   qq|	jr||	jjj d|	jjj  |	_d |	_d |	_	g |	_g |	_|	  |	  |	  |	  |	   |	j
dddd |	j!s|	  |j|	_|j|	_|	j
dddd |	j"dkr(|	||j#< q||	 q|t|$  D ]L}|j!rD|j!|krd||_!n|%|j!j#d |_!|  |j
dddd qDd S )Nc                 S   s"   i | ]}|j  d |jj |qS rw   rA   rM   r?   )r   lstr   r   r   r|  e  s      zHCmfProject.create_from_template.<locals>._copy_tasks.<locals>.<dictcomp>T)r)   Zinclude_archivedc                 S   s"   i | ]}|j  d |jj |qS r  r  )r   compr   r   r   r|  g  s      ***r   F)r  r   zlists.parentzattachments.urlzfix_versions.parentzaffected_versions.parentzcomponents.parent)r)   r0   )rw  r  )listsfix_versionsaffected_versionsr   rw   r  r   r"   z	task.epicztask.subproject)r   r  r"   )&r<   rh   rg   updaterf  r   r*   r  rM   Zop_gantt_taskr'   Z_calc_gantt_taskr   r  r  r  r   r   r)   rl   rm   r>   rA   r?   Z	main_listr  Z
spectatorsr   r  r  r  r  r  Zparent_taskr   r   r   r=   )r  orig_projectZnew_project_params_dictZorig_main_gantt_projectZnew_main_gantt_projectZ
orig_tasksZparent_tasksr  Z	orig_tasknew_taskZparams_listsZ
param_namer  r  rw  )
_copy_taskr   r   _copy_tasksc  s    


   
, z4CmfProject.create_from_template.<locals>._copy_tasksc              
   S   s   |   }| j|_| j|_||_||_|jdkrDtjj| j	j
|d|_	| |_| jr| jD ]N}t|jd,}tj||j
d}||  |  W 5 Q R X ||| qZ|jdddd |S )Nr  )rM   r)   rbr)   rM   FTr  )r  rO   Z
cmf_authorr)   r  r   r<   rx   r=   r.   rM   r  r   r  openZfull_path_filerg  Zupload_filereadr'   Z_replace_attachment)rw  r  r  ZattachfZ
new_attachr   r   r   r    s"    


z3CmfProject.create_from_template.<locals>._copy_taskTr  r`  r  )rM   r   r  Zcloned_fromF)r  r   rN  )r  r  r  )r  r  r  r  )r<   r	   r=   r5   r  rM   r'   rg   rk   r
   rh   )r   rM   r   r  r  r  ri   r   r  r  r  r   )r  r  r   create_from_templateH  s.    KzCmfProject.create_from_template)NNN)NN)rI   N)N)N)N)NN)NN)NNNNN)N)?__name__
__module____qualname__classmethodr   r   r    r,   rH   rJ   rB   r}   r   r   r   r   staticmethodr   r   r   r   r  r   r   r   r  r  r   r  r  r   r!  r7  r=  r>  rF  r'   r_  ra  rb  rc  rk  rm  rq  rv  rx  ry  rg   r~  r  r  r  r  r  r  r   r   propertyr  r  r  r  __classcell__r   r   r   r   r	      s    :& ,


  i_
1
!.]<

>


)    


 r	   c                   C   s
   t j S r   )r<   r	   rx  r   r   r   r   rt     ru   rt   c                   C   s
   t j S r   )r<   r	   ry  r   r   r   r   rt     ru   )r   r   r   r   r  r   builtinsZcmf.includeZ"modules.project.fields.cmf_projectmodulesr  r   rI   r0   Zcmf_projectr	   ZAPPZHOOK_CRON_DAILYr>   r   r   r   r   <module>   s,                f