U
    Մ:j[                     @   sn   d dl T d dlT d dlZd dlZd dlT d dlZd dlmZm	Z	m
Z
mZ dddZedd	d
ddddZdS )    )*N)OptionalListUnionAnycsvFc              
   K   s   ddl m}m} tj }	|	d}
dtjj d|
 d| }t	j
tj|d}|  |  W 5 Q R X |t| |j|||||d|d |jS )	Nr   )schedule_deferred_jobcmfutilz%Y%m%d%H%M%Szexport..)parentname)
class_nameres_attachment_idfield_namesbqlformat_fileinclude_archivedorder_by)kwargs)cmf.includer   r	   datetimenowstrftimegZcurrent_useridmodelsCmfAttachmentdisable_aclsaveexport2file_taskurl)r   r   r   r   r   r   r   r   r	   r   Zformatted_timeZexport_filename
attachment r"   ./cmf/util/cmf_export.pyexport2file   s$    


r$   u'   Экспорт данных в файл   T)descriptionpriorityZshow_bg_progressbarc           3         s  ddl ddlm ddlm  | dkr0d} tt|  tjj|d}t	dfd	d
 fdd}	dYfdd	dt
ttttt f  ddddd tdfdd}

sdd j D 
t }
D ]J}|dkrd}n.j|rtj|tjjr|d7 }|| q|
|

dkrHdd< i  fddfd d!t &}|d"kr| d#}t|d$d%d&}ddl}|j|d'd(|jd)}g 	t|	
D ]\g }
D ]}dkr	| |d*r	| d+ |}|}||}|||| |d*rֈ|d,}||j qֈdkr| 	 | | qW 5 Q R X n|d-kr<dd.l!m"} dd/l#m$} ||d0}|%d1}|&d2d3 |%d4}|| |%d5}d6|_|| |%d7}t'j(|_|| |%d8}d9|_|| |%d:}d;|_|| |%d<}|&d=d> || |%d?} ||  t|	
D ]Z\|%d@}!t) }"||! 
D ].}|*dA}#j|#d }|#d |"kr(|%|#d |"|#d < |!|"|#d   |"|#d }$t+|#d }t|tjj,r|r tt|j- jD ]>}%|%dBkr|j.|$_qjt/||%rj|$&|%t
t+||% qj|$&dC|j0 qt|tjj1tjj2fr |r |$&dC|j0 |D ]0}&|%dD}'|'&dE|&j3 |&j.|'_|$|' qnt|tjj4tjj5fr|dkrFq҈||}t|tjj4r|dk	rp|n|j6}(|dk	rt
|n|})|(|)d%|$_n4|dk	r|n|j6}(|(|dk	rt
|n|d%|$_|$&dC|j0 n t
||$_|$&dC|  qҐq|&dFt
 |&dGt
 |7|8| n|dHkrLddIl9m:}* ddJl;m<}+ ddKl;m=}, ddLl;m>}- |*? }.| dM}	
fdNdO}/|.j@dP_Ag 	r"|dQd}0|dRddSdT |	
D }1t|0D ]&\|1dsq|/  qnt|	
D ]\|/  q.|.B| ntCdU| t|dV*}2D  |jE|2dWdWdX W 5 Q R X W 5 Q R X W 5 Q R X dS )ZzN
    https://bcrm.carbonsoft.ru/project/Document/DOC-007693#spec-007668-b
    r   Nr	   )CmfActiveEntityZ
CmfRoadmapZCmfTask)r   )returnc                    s     | j}| j}t|tjjo$| j}t|tjjo8| j	}t|tjjoL| j
}t|tjjo`| j}tjj|| j|| j||d|dd	S )NreadF)	initial_acl_keyZobject_modelZobject_owner_idZ	object_idZobject_parent_idZobject_dictZaccess_levelZperm_security_level_allowed_idsZraise_error)Zget_model_by_namer   __dict__
issubclasscmfr   	CmfEntityperm_effective_acl_idZCmfModelcmf_owner_id	parent_id%perm_security_level_allowed_ids_cacheZCmfAccessListZcheck_accessr   )objmodelZobj_dictr,   Zobj_owner_idZobj_parent_idr4   r(   r"   r#   check_access_obj>   s"         z*export2file_task.<locals>.check_access_objc           	      3   s   d}d}d| krdg|  } dddddd	d
dddddg}g }t  rP|ddg7 }j||| g| | | d}|szq||7 }|D ]:}|sqtdr|}n|g}|D ]
}|V  qqqPdS )u(  
        Генератор для постраничной загрузки данных с проверкой прав доступа.

        Загружает данные пакетами по 50000 записей, фильтрует по правам доступа
        и возвращает только разрешённые записи.

        Args:
            fields: Список полей для экспорта. Если '--' отсутствует, добавляется в начало.

        Yields:
            Записи, к которым пользователь имеет доступ на чтение.

        Note:
            Для проверки доступа автоматически подключаются служебные поля:
            - cmf_owner_id, cmf_author_id — владелец и автор
            - access_author, access_responsible — права автора и ответственного
            - perm_security_level_id — уровень безопасности
            - responsible_id, spectators, executors — исполнители и наблюдатели
            - project_id, parent_id — иерархия
            - perm_effective_acl_id, perm_security_level_allowed_ids_cache — кэш ACL
        r   iP  z--r2   Zaccess_authorZcmf_author_idZperm_security_level_idZaccess_responsibleZresponsible_idZ
spectatorsZ	executors
project_idr3   r1   r4   Z
logic_typeZactivity)filterslicefieldsr   r   export_hookN)r.   Zslisthasattrr<   )	r;   startstepZsecurity_fieldsZpreload_fieldsdatarowZrowsZsub_row)r)   r   r7   clsr   r   r"   r#   paginate_dataM   sJ    
         



z'export2file_task.<locals>.paginate_datac                    s&  | d krdS t | tjr"| dS t | tjr8| dS t| drLt| jS t| dr`t| jS t | trd	 fdd| D S |rt
|tjjr|d k	r|n|j}|d k	rt| n| }||t| S |rt
|tjjr|d k	r|n|j}||d k	rt| n| | S | rt| S dS d S )	N z%d.%m.%Y %H:%Mz%d.%m.%Yr   r   ,c                    s   g | ]} |qS r"   r"   ).0rA   convert_valr"   r#   
<listcomp>   s     z9export2file_task.<locals>.convert_val.<locals>.<listcomp>)
isinstancer   r   dater=   strr   r   listjoinr.   r/   r;   CmfChoiceIntchoicesget	CmfChoice)val	field_objchoices_overriderP   
lookup_keyrG   r"   r#   rH      s(    






z%export2file_task.<locals>.convert_valzSimpleMapper.SimpleModel)r5   	field_strr*   c                    sd   t | |rt| |S | }|dD ]< |dkr4 dS t|trR fdd|D }q"t| d}q"|S )u#  
        Получаем значение поля объекта по пути (путь может содержать точку для вложенных полей)
        Поддерживает вложенные поля и поля m2m-связей

        Например:
        - get_included_attr(doc, 'person.second_name')
        - get_included_attr(doc, 'tags.name') - m2m связь

        Возвращает единственное значение поля, либо список значений, или None
        r
   Nc                    s   g | ]}t | d qS N)getattr)rF   itemfieldr"   r#   rI      s     z?export2file_task.<locals>.get_included_attr.<locals>.<listcomp>)r=   rY   splitrJ   rM   )r5   rW   Zcurr"   r[   r#   get_included_attr   s    


z+export2file_task.<locals>.get_included_attrc                 S   s   | d}| }t|D ]\}}t||d}|sDt|drD|j|}|t|d ksX|s`|  S t|dr|tt|j	}qt|dr|jrtt|jd }q dS qdS )u   
        Рекурсивно получает объект поля, учитывая вложенность через точку.
        r
   Nr;      r6   r   r   )
r]   	enumeraterY   r=   r;   rQ   lenvarsr   r6   )	class_obj
field_namepartsZcurrent_objipartrT   r"   r"   r#   get_field_obj   s    

z'export2file_task.<locals>.get_field_obj)fields_namec                    s,    fdd i }| D ]} |||< q|S )Nc           	   	      s   | d}| j|d }ddi}|sV| j| krVtt|| j  }|j|d }|}ttt}tjj	|d< |r|j
}t|dkrt|dr|jr|jd }nt|dr|j}n|S | d || d|dd   }|S )	Nr
   r   ZCmfTestplanTestcaseZCmfTestcaser0   r_   r   r6   )r]   r;   rQ   r   keysrb   r   copyr/   r0   captionra   r=   r6   rN   )	rc   rd   pural_namesr\   Zlinked_entityZlinked_class_objresZ
models_clsZ
model_nameget_captionr"   r#   rp      s*    
 
&z;export2file_task.<locals>.get_captions.<locals>.get_captionr"   )ri   rn   rd   )rB   ro   r#   get_captions   s
    z&export2file_task.<locals>.get_captionsc                 S   s   g | ]}|j r|jqS r"   )Zvisibler   )rF   r\   r"   r"   r#   rI      s      z$export2file_task.<locals>.<listcomp>Ztimetracker_historyzop_gantt_task.actual_workz.nameuG   Журнал работ.Фактические трудозатратыc                    s   t  sd S t| dd }|s"d S t|tt| dd tt| dd |f}|krZ| S | }d }|r|di |r|d | d}||< |S )Nr8   Zlogic_type_idZactivity_idZ	ui_fieldsrP   )r.   rY   rL   Z_build_ui_formrQ   )rA   rd   r8   Z	cache_keyZui_form_customresult)r)   _row_choices_cacherB   r"   r#   get_row_field_choices  s$    

z/export2file_task.<locals>.get_row_field_choicesc                    s(   |r$t |tjjtjjfr$ | |S d S rX   )r.   r/   r;   rO   rR   )rA   rd   rT   )rt   r"   r#   get_choices_override  s    
z.export2file_task.<locals>.get_choices_overrider   z/export.csvzw+rD   )newline;")Z	delimiterZ	quotecharZquotingtext    без htmllxmlZxml)ElementTree)Pathz
export.xmlrssversionz0.92channeltitleZEvaTeamlinkr&   u+   XML представление данныхlanguagezru-rutaskr>   0
build_inforZ   r
   r   rl   valuer   endtotalZxlsx)workbook)open_workbook)XL_CELL_DATE)xldate_as_tuplez/export.xlsxc                     s  g } D ]B}
dkrF | |drF | d rb|dkrb|  
d  qr|dkrtg }dd |D }|  d	| qr|d
krtg }dd |D }|  d	| qr|dkr|  t q	|}|}||}|  ||| |dr 	|d}	|  |	j q
dkrb   |  r҈ }
j	}j
| }t|
d|_|
dk|_j|dd}|jd k	rd|
d   |j |_d S )Nr   ry   rz   Zcustom_column_sequence_numberr_   Zcustom_column_predecessorsc                 S   s   g | ]}t t|d qS rX   rL   Zroadmap_sequence_maprQ   rF   tidr"   r"   r#   rI     s     z7export2file_task.<locals>.write_row.<locals>.<listcomp>z; Zcustom_column_followersc                 S   s   g | ]}t t|d qS rX   r   r   r"   r"   r#   rI     s     Zcustom_column_indicatorsr{      )rA   column    )appendrQ   endswithZpredecessors_ofrN   Zfollowers_ofZ_indicator_textBeautifulSoupry   Zmax_rowZrow_dimensionsminZoutlineLevelZhiddenZcellr   )csv_rowr\   ZpredecessorsZ sequence_numbers_of_predecessorsZ	followersZsequence_numbers_of_followersfield_valuerT   rU   soupdepthZxl_rowZrdZ
first_cell)bs4captionsrB   rH   csv_headr   from_roadmapru   rh   r^   rf   roadmap_level_ofrA   
sheet_xlsxr   r"   r#   	write_row  sJ    









z#export2file_task.<locals>.write_rowu   Выгрузкаroadmap_ordered_idsr   c                 S   s   i | ]}t |j|qS r"   )rL   r   )rF   r5   r"   r"   r#   
<dictcomp>  s      z$export2file_task.<locals>.<dictcomp>u7   Это формат не поддерживается: rbF)ZbackupZmake_preview)NN)Fr   r   r	   Zcommon.models.cmf_active_entityr)   rb   r   r   rQ   boolrL   r   r   r   r   rM   r;   valuesr.   r/   Z
CmfRelBaser   tempfileZTemporaryDirectoryopenr   writerZQUOTE_MINIMALr`   r   r   ry   ZwriterowZ	xml.etreer|   pathlibr}   ZElementsetZrequestr    dictr]   rY   ZCmfRelationBaser   r   r=   rl   Z
CmfM2MBaseZCmfBackrefBaser   rO   rR   rP   write_bytesZtostringZopenpyxlr   Zxlrdr   r   r   ZWorkbookZactiver   r   	Exceptionr   Zupload_stream_file)3r   r   r   r   r   r   r   r   r!   rC   rq   Z
new_fieldsrd   ZtmpdirZ	file_pathZcsvfiler   r   r   r\   r   rT   rU   r   ZETr}   r~   r   r   r   r&   r   r   rZ   elementsrm   Z
field_infokeyvr   rP   rV   r   r   r   r   Z	book_xlsxr   r   Z	id_to_objfr"   )r)   rs   r   r   r   r7   rB   r	   rH   r   r   r   ru   rh   r^   rt   rf   r   r   r   rA   r   r   r#   r   '   s4   ?"&


 




























 

(0

r   )NNNr   FN)NNr   FN)r   Z
cmf.configr   Z
cmf.fieldsr/   rk   r   typingr   r   r   r   r$   Zcmf_deferred_jobr   r"   r"   r"   r#   <module>   s   
     