U
    jg@                     @   sB   d dl T d dlmZ d dlmZ d dlmZ G dd dejZdS )    )*)cmf_roadmap)aliased)defaultdictc                       s   e Zd ZdZejjdg Zdd Zdd Z fddZ	 fd	d
Z
eeddddddd Zeg g g g g g g g g g g g g g g g g g g g g g ddfddZ  ZS )
CmfRoadmapTncget_filtered_roadmap_by_levelc                    s    fdd  | j jS )Nc                    s0   | sd S | j dkr| S | j   | jjS d S )NZ
CmfProject)
class_nametree_parentloadvalue)childroot_parent './modules/project/models/cmf_roadmap.pyr      s    

z,CmfRoadmap._calc_parent.<locals>.root_parent)r	   r   selfr   r   r   _calc_parent   s    zCmfRoadmap._calc_parentc                 C   s   | j js| jsd S d| _d S )NZgantt)Z
logic_type
is_changedis_newZui_view_formr   r   r   r   _calc_ui_view_form   s
    zCmfRoadmap._calc_ui_view_formc                    s   t   ddg S )Nzmembers.responsibleztree_parent.activity)supersave_preload_fieldsr   	__class__r   r   r       s    zCmfRoadmap.save_preload_fieldsc                    s  | j s|  | _ | j r.| j jdddddgd | jsP| jrP| jj rP| jj| _| jsr| j rr| j j rr| j j| _| jstjjddd	| _| j	r| j r| j j
s| jpd
 | _nL| jr| jjds| j r| j jdkrd| jpd
 | _nd| jpd
 | _| jr"| jjs| jjr"tddd t j||}| jjrFttjj | j jr| j r| jD ]4}|j  | j kr^| j |_ |j|ddi| q^|S )NZ	cmf_ownerZcmf_owner_assistantsactivitylogic_prefixadd_object_typeZfieldsZ
productionT)codeZcache_inmemory1)ZRoadmapu   Дорожная картаzproject.baseu   Дорожная карта zRoadmap uL   Нельзя изменять memrers и tasks у корневого Roadmap)abortnotifyF)parentr   Zload_fieldsr   r	   r
   modelsZCmfActivitygetr   r   namer   
startswithr   systemmembersr   ZtasksZ	cmf_alertr   saveZschedule_deferred_jobr   recalculate_cache)r   argskwargsresmemberr   r   r   r*   #   s>    




zCmfRoadmap.save<      )Z	only_onceZsoft_time_limitZ
system_jobpriorityc               	   K   s   t j}d}d}|jddgdD ]}|d7 }t|j}|j|kr|d7 }td|j d| d|j  ||_|j	d	d
 |jj
|jj
d}td|j | td| |d dkrt  qtd| d| d |S )u;   Актуализация кеша кол-ва членов.r   cache_members_countr)   r      zUpdate cache_members_count z ->  T)Z	only_data)Znode_idZelements_countztree-node-count-changes-ztree-node-count-changes2   zRecalculate /z roadmaps caches)r$   r   listlenr)   r3   gdebugidr*   r   Zcmf_emit_eventZ
cmf_commit)_kwargsclsZtotal_countZ
calc_countr   Z
real_countZ
event_datar   r   r   r+   Q   s$    

 
zCmfRoadmap.recalculate_cacheFc           P      C   s  ||||||||	|
|||||||||||g}t jj}t jjj}| }t|dd}t|dd}t|dd}t|dd}t|dd} t|dd}!t|dd}"t|d	d}#t|d
d}$t|dd}%t|dd}&t|dd}'t|dd}(t|dd})t|dd}*t|dd}+t|dd},t|dd}-t|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	d!|(j	d"|)j	d#|*j	d$|+j	d%|,j	d&|-j	d'|.j	d(
|||j|jk||j|jk||j|jk||j|jk| | j|jk|!|!j| jk|"|"j|!jk|#|#j|"jk|$|$j|#jk|%|%j|$jk|&|&j|%jk|'|'j|&jk|(|(j|'jk|)|)j|(jk|*|*j|)jk|+|+j|*jk|,|,j|+jk|-|-j|,jk|.|.j|-jk}/|j| |d) gt j||/d*\}/}0|/|0}/|/ }1tt}2|1D ]d}3td+d,D ]R}4|3|4d+  }5|4d+krd-n
|3|4d.  }6|5d-k	r||5|2|4 kr||6g|2|4 |5< q|qntt}7|rt jj}8t jjd/d0j}9td.d,D ]}:t|2|:d+   };|;s&q||8j|8j|8jd1k|8j|9k|8j|; }<|<D ]r\}=}>|=}6|>}5|5|2|: kr|2|: |5 |6 n|6g|2|: |5< |5|7|: kr|7|: |5 |6 n|6g|7|: |5< q\qi }?td+d,D ]}:g }@|2|:  }Ag }B|AD ](}5|2|: |5 D ]}C|B|5|Cf qq |:d+krT||:d+  rT|@||:d+   |r|:d+kr|rd2d3 |?|:d+  D }Dg }E|7|:  D ]0\}F}G|GD ] }H|H|Dkr|E|F  qqqd4|d5d6|Dgd7d6|Egg}|@| |@rr||j|j|A}I|j|@t j||Id*\}I}0|I|0}I|I }Jt }B|JD ]0}3|2|: |3d)  D ]}C|B |3d) |Cf qLq8t|B}B|B|?|:< q|rtd8d+d9D ]p}K|?|K rt }L|?|K D ]0\}M}N|2|Kd+  |N D ]}O|L |N|Of qĐqtt|?|Kd+  |LB |?|Kd+ < q|?S ):u8  
        1) Делаем большой запрос с 20 JOIN (T1..T20) и узнаём, какие задачи есть на каждом уровне.
        Сохраняем в levels_dict = {1: {id: parent_id, ...}, 2: {id: parent_id, ...}, ...}.

        2) Для каждого уровня (1..20) делаем новый запрос, где:
        - Условие: CmfTask.id IN (levels_dict[level])
        - Плюс фильтр по уровню — если он задан
        - Плюс глобальный фильтр — если он задан

        3) Результат: словарь {1: [(id_1, parent_id_1), (id_1, parent_id_2), ...], 2: [...], ..., 20: [...]},
        где лежат уже отфильтрованные задачи на данном уровне.
        T2)r&   T3T4T5T6T7T8T9T10T11T12T13T14T15T16T17T18T19T20Zlvl1_idZlvl2_idZlvl3_idZlvl4_idZlvl5_idZlvl6_idZlvl7_idZlvl8_idZlvl9_idZlvl10_idZlvl11_idZlvl12_idZlvl13_idZlvl14_idZlvl15_idZlvl16_idZlvl17_idZlvl18_idZlvl19_idZlvl20_idr   )Z	in_filterZmodelZsa_modelqueryr4      N   zsystem.additional_parent)r   Fc                 S   s   g | ]\}}|qS r   r   ).0tid_r   r   r   
<listcomp>8  s     z>CmfRoadmap.ncget_filtered_roadmap_by_level.<locals>.<listcomp>ORparent_task_idINr<      )!r$   ZCmfTaskZdp_modelZdpdata_driverZSessionr   rR   r<   Zlabelselect_fromZ	outerjoinrZ   Zcollect_filter_expfilterallr   dictrangeZCmfRelationOptionZCmfRelationTypesgetr8   keys
in_link_idout_link_idZcmf_deletedZrelation_type_idZin_appenditemssetadd)PZinsert_bql_listZglobal_bql_listZlvl1_bql_listZlvl2_bql_listZlvl3_bql_listZlvl4_bql_listZlvl5_bql_listZlvl6_bql_listZlvl7_bql_listZlvl8_bql_listZlvl9_bql_listZlvl10_bql_listZlvl11_bql_listZlvl12_bql_listZlvl13_bql_listZlvl14_bql_listZlvl15_bql_listZlvl16_bql_listZlvl17_bql_listZlvl18_bql_listZlvl19_bql_listZlvl20_bql_listZshow_additional_tasksZshow_sub_itemsfiltersZTaskr^   Zsessionr?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   Zquery_filterZrowsZlevels_dictrowZlevel_indexZtask_idrZ   Zadditional_levels_dictZRelationZ"additional_parent_relation_type_idlevelZprev_level_idsresultsrf   rg   Zfinal_levels_dictZcondsZ	level_idsZlevel_ids_with_parentZparent_taskZprevious_level_idsZadditonal_tasks_of_prev_levelZadd_task_idZadd_task_parent_idsZadd_task_parent_idZquery_nZfiltered_idslZparent_ids_setZ_idZ	parent_idZgrand_parent_idr   r   r   r   m   s   '




















 
 
 
 
 
 
 
 
 
  
! 
" 
# 
$ 
% 
& 
' 
( 
) 
,











$z*CmfRoadmap.ncget_filtered_roadmap_by_level)__name__
__module____qualname__Z	api_allowr   r   Zapi_methodsr   r   r   r*   staticmethodZcmf_deferred_jobr+   r   __classcell__r   r   r   r   r      sF   .r   N)Zcmf.includeZmodules.project.fieldsr   Zsqlalchemy.ormr   collectionsr   r   r   r   r   r   <module>   s   