
    G&jfE                         d dl Z d dlmZ d dlmZmZ d dlmZ d dlm	Z	 dddd	d
Z
ddddZddddZg dZdZdZd Zd Zd Zd Zd Zd Zd Zd ZddZ G d de	      Zy)     N)defaultdict)
base_errorfields)models)ExportDataManageru   ОНu   ООu   ННu   НО)zsystem.finish:startzsystem.finish:finishzsystem.start:startzsystem.start:finishu   Фиксированнаяu   Не раньшеu   Не позже)0-constz3-afterz4-beforeu   Фиксированный)r   z1-afterz2-before)z op_gantt_task.actual_finish_datezop_gantt_task.sched_finish_datez"op_gantt_task.constrain_start_typez"op_gantt_task.constrain_start_datez#op_gantt_task.constrain_finish_typez#op_gantt_task.constrain_finish_datedeadlineu   Не назначеноzop_gantt_task.c                     t        t              } t        t              }g d}ddt        t        j                               g}t        j
                  j                  ||      D ]  }t        j                  |j                  j                  d      }| |j                     j                  |j                  |f       ||j                     j                  |j                  |f        | |fS )N)z--out_link_id
in_link_idrelation_type.coder   IN)r   filter )r   listRELATION_CODE_LABELkeysr   CmfRelationOptionslistgetrelation_typecoder   appendr   )followers_ofpredecessors_of_fields_filterrelr   s         )./modules/project/utils/roadmap_export.py$_prepare_predecessors_followers_mapsr    +   s    t$L!$'OGG#T40C0H0H0J+KLG''--WW-M H"&&s'8'8'='=rBS__%,,cnnd-CD'../FGH ((    c                     g }| D ]J  \  }}|j                  |      }||j                  t        |            }|6|j                  | |        L dj                  |      S )Nz; )r   strr   join)pairssequence_mapparts	linked_idr   seqs         r   _format_relationsr*   7   sm    E  )	4y);""3y>2C?LLC5() 99Ur!   c                    t        | t        j                        r| j                  d      S t        | t        j                        rDt        j                  | j                  | j
                  | j                        j                  d      S y)Nz%d.%m.%Yr   )
isinstancedatetimestrftimedateyearmonthday)ds    r   _format_dater4   C   s^    !X&&'zz*%%!X]]#  !%%8AA*MMr!   c                 ^   t        | dd       }|syt        |dd       }|rdt        |       dS g }t        |dd       }|t        v rAt        |   }d| d}t        |d	d       }|r|d
t        |       dz  }|j                  |       t        |dd       }|t        v rAt        |   }d| d}t        |dd       }	|	r|d
t        |	       dz  }|j                  |       t        | dd       }
t        |dd       }|r%|
r#||
kD  r|j                  dt        |
       d       dj                  |      S )Nop_gantt_taskr   actual_finish_dateu   Была завершена ""constrain_start_typeu/   Установлено ограничение "u    " для "Дата начала"constrain_start_dateu    на "constrain_finish_typeu&   " для "Дата окончания"constrain_finish_dater	   sched_finish_dateuS   Указана дата окончания позже крайнего срока "
)getattrr4   START_RESTRICTION_LABELr   FINISH_RESTRICTION_LABELr$   )instance
gantt_taskactual_finishlines	cst_valuelabellinecsd	cft_valuecfdr	   sched_finishs               r   _indicator_textrM   K   s   ?D9JJ(<dCM.|M/J.K1MME
$:DAI++'	2@Gghj"8$?gl3/022DT
$;TBI,,(3@Gmnj"94@gl3/022DTxT2H:':DAL\H%<jkw  yA  lB  kC  CD  E  	F99Ur!   c                 f    t        | t              xr  t        d | j                         D              S )uy   Проверяет лист группировки Roadmap: уровни уже содержат строки задач.c              3   f   K   | ])  \  }}t        |t              xr t        |t               + y wN)r,   intr   ).0levelitemss      r   	<genexpr>z!_is_level_dict.<locals>.<genexpr>r   s2      +E5 	5#::eT#::+s   /1)r,   dictallrT   )values    r   _is_level_dictrY   p   s0    eT" s +!KKM+ ( r!   c                   	
 t        t              	t        t              }g }t               }t        d | D              D ]  }| |   D ]v  }|d   }t	        |      dkD  r|d   nd}|r1|||   vs'||   j                  |       	|   j                  |       P||vsU|j                  |       |j                  |       x  g 
t               	
fd|D ]
  } |        
S )u   Сворачивает уровни Roadmap в плоский XLSX-порядок: родитель перед потомками.c              3   B   K   | ]  }t        |t              s|  y wrP   )r,   rQ   )rR   rS   s     r   rU   z4_ordered_task_ids_from_level_dict.<locals>.<genexpr>   s     Q%*UC:PQs   r      Nc                     | v ryj                  |        j                  |        j                  | g       D ]
  } |        y)ur   Добавляет задачу один раз и затем всех потомков в порядке Roadmap.N)addr   r   )tidchild_idchildren_mapordered_idsvisitedwalks     r   rd   z/_ordered_task_ids_from_level_dict.<locals>.walk   sJ    '>C3$((b1 	HN	r!   )r   r   setsortedlenr^   r   )levels_dictchildren_seenroots
roots_seenrS   rowtask_id	parent_idroot_idra   rb   rc   rd   s            @@@@r   !_ordered_task_ids_from_level_dictrp   x   s    t$L$MEJQ;QQ 
&u% 		&C!fG"%c(Q,ADI-	"::!),009 +227;
*w'W%		&
& KeG  W r!   c                     | sd| fS | j                  t              }|rt        j                  nt        j                  }|r| j                  dd      d   n| }t        ||d      |fS )ux   Возвращает поле модели для группировки, учитывая op_gantt_task-префикс.N.r\   )
startswithGANTT_PREFIXr   CmfGanttTaskCmfTasksplitr?   )
field_nameis_gantt_taskmodelplain_field_names       r   _group_field_objr|      se    Z)),7M#0FfnnE6Cz''Q/25*D13CCCr!   c           	         |ddg fv rt         S t        |       \  }}|st        |      S t        |t        j
                        rH|j                  j                  ||j                  j                  t        |      t        |                  S t        |t        j                        r.|j                  j                  t        |      t        |            S t        j                  t        j                  t        j                  f}t        ||      rt        |dd      }|st        |dd      r|j                  d   }|r|dk(  r)t        |t              rd|v r|j                  dd      d   }t        |t              rt        t        |d      n|}|r-	 |j                  |d	g
      }|r|j&                  j(                  S t         S t        |      S # t         j"                  t$        f$ r	 t         cY S w xY w)u   Возвращает заголовок группы; пустые/недоступные relations дают «Не назначено».Nr   rz   r   r   	CmfEntity:r\   name)r   )UNASSIGNED_GROUP_LABELr|   r#   
issubclassr   CmfChoiceIntchoicesr   	CmfChoiceCmfRelationCmfGenericRelation
CmfM2MBaser?   r   r,   rw   r   CmfErrorLookupErrorr   rX   )rx   key	field_obj_plain_field_namerelation_fields
model_namerz   objs           r   _group_labelr      s   
tRn &%#3J#? I 3x)V001  $$S)*;*;*?*?C#c(*STT)V--.  $$SXs3x88))6+D+DfFWFWXO)_-Y6
gi4@"))!,JjK7ZS=QVY]`V`3*1-J5?
C5P
D1V`.iiVHi5
 xx~~%%%s8O ''5 . .-.s   G G.-G.c           	      8   t        |       rt        |       D cg c]  }d|d	 c}S g }|t        |      k  r||   nd}| j                         D ]C  \  }}|j	                  dt        ||      |d       |j                  t        |||dz                E |S c c}w )uy  Строит плоский поток строк XLSX с group-header строками вместо UI-дерева.

    Подпись группы намеренно попадает в `name`/«Наименование», потому что
    Excel не имеет дерева, а иерархию нужно сохранить в плоской выгрузке.
    task)typeidNgroup)r   r   depthr\   )rY   rp   rg   rT   r   r   extend_build_grouped_export_rows)rX   group_fieldsr   rm   rowsgroup_field	group_keynested_values           r   r   r      s     e =UC
 7+
 	

 D).\1B)B,u%K#(;;= W	< 	 i8
 	
 	.|\5ST9UVW K!
s   Bc                   H     e Zd Z	 	 d fd	Zd Zd Zd Zd Zd Zd Z	 xZ
S )	RoadmapExportDataManagerc                     || _         t        t              d   }t        	|   |||||fi | |xs i | _        g | _        g | _        g | _        i | _	        i | _
        i | _        i | _        y )Nrv   )roadmap_clsvarsr   super__init__filter_settingsr   export_rowsrb   r&   level_ofr   r   )
selfclsbqlinclude_archivedorder_byforced_captionsr   kwargstask_cls	__class__s
            r   r   z!RoadmapExportDataManager.__init__   s{     <	*3(8(O^W]^.4"!r!   c                       j                   j                  d	i  j                  } j                  j                  d      xs g  _        g  _        i  _        i  _         j                  rt        | j                         _	        t               } j                  D ]M  }|j                  d      dk7  r|d   }||vs"|j                  |        j
                  j                  |       O dd j
                  g _        yg  _	        t        t              t        t              }g }t               }|j!                         D ]{  \  }}	t#        |t$              s|	D ]`  \  }}
}|
r1|||
   vs||
   j                  |       |
   j                  |       :||vs?|j                  |       |j                  |       b } t                fd|D ]  } |d        dd j
                  g _        y)
uu   Готовит BQL задач и служебные структуры для плоского XLSX-экспорта.group_by_fieldsr   r   r   r   Nc                 4   | v ry j                  |        j                  j                  |        t        j                        }| j                  vr|j                  | <   |j
                  | |f<   j                  | g       D ]  } ||dz           y )Nr\   )r^   rb   r   rg   r&   r   r   )r_   rS   sequence_numberr`   ra   r   rc   rd   s       r   rd   z.RoadmapExportDataManager.prepare.<locals>.walk$  s    g~KK##C(!$"2"23O$+++)8!!#&49DMM301(,,S"5 *Xuqy)*r!   r    )r   ncget_filtered_roadmap_by_levelr   r   r   rb   r&   r   r   r   re   r^   r   r   r   r   rT   r,   rQ   )r   roadmapseen_ids
export_rowrm   ri   rj   rk   r   tuplesrn   _root_idro   ra   rc   rd   s   `            @@@r   preparez RoadmapExportDataManager.prepare   s    C$""BBZTEYEYZ 00445FGM29'4CTCTUDuH".. 5
>>&)V3$T*(*LL)$$++G45 dD$4$45DH"4(#C(U
"==? 	.KCc3'06 .,HmI&>>%i044W=$Y/66w?j0"w/W-.	. %
	*  	G!	 $ 0 01r!   c                      dgt        |      z   S )Ncustom_column_sequence_number)r   )r   field_namess     r   get_extra_field_namesz.RoadmapExportDataManager.get_extra_field_names5  s    /043DDDr!   c                     dddddS )Nu   Индикаторыu   №u   Предшественникиu   Последователи)custom_column_indicatorsr   custom_column_predecessorscustom_column_followersr   )r   s    r   get_forced_captionsz,RoadmapExportDataManager.get_forced_captions8  s    (>-2*J'C	
 	
r!   c                 &   i }d|v rt        |      |d<   |r3t        | j                  j                  |g       | j                        |d<   |r3t        | j
                  j                  |g       | j                        |d<   d|v rt        |      |d<   |S )u   Формирует вычисляемые колонки Roadmap без изменения исходной строки задачи.r   r   r   r   )r#   r*   r   r   r&   r   rM   )r   rl   r_   
row_numberr   need_predecessorsneed_followers	overridess           r   _task_override_valuesz.RoadmapExportDataManager._task_override_values@  s    	*k99<ZI566G$$((b143D3D7I23 3D!!%%c2.0A0A4I/0 &44CC4HI01r!   c           	   #     K   g }g }| j                   D ]  }|j                  d      dk(  rH|j                  dd      }|D 	cg c]  }	|	j                  dd      |k  r|	 }}	|j                  |       _t        |j                  d            }
|j                  |
      s|j	                  |       g }|j                  i |d|
i        i | _        t        |d      D ]I  \  }}|j                  d      }
|j                  d      dk(  s,|
| j
                  vs;|| j
                  |
<   K t        |d      D ]  \  }}|j                  d      dk(  rJ|D ci c]  }|d	 }}d
|v rt        |      |d
<   d|v r|j                  d      xs t        |d<   dd|f d|j                  d      }|j                  |      }	| j                  |	|||||      }|	d|f  yc c}	w c c}w w)up  Итерирует видимые задачи и group-header строки для плоского XLSX.

        Заголовки групп выдаются только перед первой доступной задачей группы,
        чтобы Excel без tree widget сохранил UI-иерархию без пустых групп.
        r   r   r   r   r   r\   startr   r   r   r   N)	r   r   r   r#   r   r&   	enumerater   r   )r   r   	id_to_objr   r   visible_export_rowspending_group_rowsr   r   rl   rm   r   r   fieldr   r_   s                   r   _iter_grouped_rows_for_xlsxz4RoadmapExportDataManager._iter_grouped_rows_for_xlsxQ  s&     !** 	JJ~~f%0 #w2#5&www*U2 &" & #))*5*.../G}}W%#**+=>%'"#**+Hj+H$+HI!	J$ +45HPQ+R 	='OZ nnT*G~~f%/G4CTCT4T-<!!'*	=
 '00C1&M 	$"J
~~f%04?@5UBY@	@2kAADZI=>[((2v(>(XBXIf%Ay((..&C--$C22S*k3DnI q)##	$'&* As1   >G' G?G'A+G'
G'<G'
G"BG'c           	   #   H  K   g }d|v rt        t              }d|v }d|v }|s|rt               \  | _        | _        | j                  ||z         D ci c]  }t        |j                        | }}| j                  r| j                  ||||      E d{    yd}t        | j                  d      D ]e  \  }}	|j                  t        |	            }
|
s#| j                  j                  |	|fd      }| j                  |
|	|dz   |||      }|
||f |dz  }g yc c}w 7 w)uj   Возвращает контракт cmf_export: (row, depth, overrides) для задач и групп.r   r   r   Nr   r\   r   )r   INDICATOR_EXTRA_FIELDSr    r   r   paginate_datar#   r   r   r   r   rb   r   r   r   )r   r   additional_fieldsr   r   r   r   rendered_idxr)   r_   rl   r   r   s                r   iter_rows_for_xlsxz+RoadmapExportDataManager.iter_rows_for_xlsx  sN     %4 $%; <8KG2kA6Z6\3Dt3151C1CKRcDc1de#S[#%e	e77Y(9>   !$"2"2!< 		HC--C)CMM%%sCj!4E22S,*K9JNI ui''AL		 fs   AD"D.%D"D BD")NN)__name__
__module____qualname__r   r   r   r   r   r   r   __classcell__)r   s   @r   r   r      s/    MQ!%":2xE
"/$br!   r   )r   )r-   collectionsr   cmfr   r   cmf.includer   cmf.util.cmf_exportr   r   r@   rA   r   r   rt   r    r*   r4   rM   rY   rp   r|   r   r   r   r   r!   r   <module>r      s     # "  1 "" !	  ,"!  ,"!   3 	)	"J"JD$N4y0 yr!   