B
    af9                 @   s   d dl Z d dlZd dlmZ d dlZd dlmZ d dlmZm	Z	 d dl
Z
d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dlT d dlmZ d dlmZ G d	d
 d
ejZdS )    N)deepcopy)Path)DictIterator)cached_property)*)cmf_plugin_csv)cmf_contextc               @   sz  e Zd ZU dZe ed< dZdd Ze	dd Z
edd	d
Ze	ee dddZdd Ze	eeef dddZdd ZeeedddZdd Zdd Zdd ZdJedddZdKedd d!Zd"d# Zd$d% Zed&d'd(Zd)d* Zd+d, Z d-d. Z!d/d0 Z"d1d2 Z#d3d4 Z$d5d6 Z%d7d8 Z&e'j(e'j)e*d9d:d;d<d= Z+dLd>d?Z,d@dA Z-dBdC Z.dDdE Z/dFdG Z0dHdI Z1dS )MCmfPluginCsvN_loggerr   c             C   s   t  d | _| jjd| jd  ddd tjrBttj| j| _| jjdtj dd t	 j
}| jjdt|d  d	dd tt|d
 | j| _| jstdd S )N   z
cpu_count=u%   , надо не менее 2 ядерT)Z	anonymouszconfig.IMPORT_PROCESS=zavailable_memory=i   @u-   Гб, по 2 Гигабайта на ядроl        u   Ресурсов системы недостаточно для импорта, обратитесь в техподдержку для дополнительной информации.)multiprocessing	cpu_countmax_processes
cmf_importlogconfigZIMPORT_PROCESSminpsutilZvirtual_memoryZ	availableint	Exception)selfZavailable_memory r   +./modules/settings/models/cmf_plugin_csv.py_prepare_multiprocessing   s     

z%CmfPluginCsv._prepare_multiprocessingc              C   s   dt j t jjddt j t jjddt j t jjddt j t jjddt j t jjddt j	 t j	jddt j
 t j
jdd	t j t jjdd
t j t jjdg	} | S )uR   Собственный магазин при выборе импорта из Jirau#   Поля пользователей)captionfieldsiconu!   Поля контрагентовu   Поля задачu,   Оперативная гант-задачаu   Журнал работu!   Поля комментариевu   Поля проектовu"   Поля списков задачu   Поля групп)models	CmfPersonimport_shop_fieldsr   
CmfCompanyCmfTaskCmfGanttTaskCmfTimeTrackerHistoryZCmfTimeTracker
CmfComment
CmfProjectCmfListZCmfPersonGroup)resr   r   r   calc_models_settings5   s$    














z!CmfPluginCsv.calc_models_settings)returnc          	   C   s   |j }d}d}y$| |}xt|D ]\}}q$W W n tk
rr   d| d| }| j| t|dd d}Y nb tk
r   | jd| d|  d}Y n4 tt	fk
r   | jd| d|  d}Y nX |S )	NFr   uK   Не корректный формат загружаемого файла :T)abortu*   Приложен пустой файл CSVu5   Не удаётся прочитать строчку)
full_path_file	_get_file	enumerateUnicodeDecodeErrorr   	exceptionZ	cmf_alertStopIterationIOError
ValueError)r   
attachmentZ	file_path
have_errorZnum	file_read_msgr   r   r   _check_fileM   s&    

zCmfPluginCsv._check_filec          	   c   s   t | j}|jdkrPtt|}|d}x| D ]}dd |D V  q6W n|jdkrt	t|}|j
}xf|jddD ]
}|V  q|W nJ|jdkrtd	 t|d
&}xtj|dddD ]
}|V  qW W d Q R X d S )Nz.xlsr   c             S   s   g | ]
}|j qS r   )value).0itemr   r   r   
<listcomp>i   s    z*CmfPluginCsv._get_file.<locals>.<listcomp>z.xlsxT)Zvalues_onlyz.csvi r;")Z	delimiterZ	quotechar)r   r-   suffixxlrdZopen_workbookstrZsheet_by_indexZget_rowsopenpyxlZload_workbookZactiveZ	iter_rowscsvZfield_size_limitopenreader)r5   Zattachment_file_pathZworkbookZ	worksheetelfiler   r   r   r.   b   s"    





zCmfPluginCsv._get_filec          	   C   s  |j | _|jsd S tjjdgdd|jgdgd}dg d}tjj|dd	d
ddggdgdgd}| |}|rpg S | 	|}| 
 }x<t|D ].\}}	|dkr|jd sP n
|dkrP xt|	D ]\}
}d}|dkr|r`|jd r`xrt|jd D ]`}d|krd|krP |d dkr&qx4|d D ](}|d |kr0|d | d}P q0W qW |s|d |d d d d q|d |
 }||d }||d< |r||d< |d |d< qW qW |d s| jd g S |gS )Nz-cmf_modified_atidz!=json_settings)order_byfilterr   ZCSV)namer   	file_typeINz.csvz.xlsz.xlsxurl)parentrN   rM   r   r   	first_rowr   Fimport_settingsrO   r   titleT)rV   file_valmodel_fieldr   rW   rX   r   u*   Приложен пустой файл CSV)loggerr   Zattachmentsr   	CmfImportgetrK   CmfAttachmentr:   r.   _default_mapping_csvr/   rL   r   appendr1   )r   r   Zprev_settingssettingsr5   r6   r7   default_mappingirowjvalfoundZprev_setZ
prev_fieldZrow_settingsrX   r   r   r   calc_import_settingsv   s`    






z!CmfPluginCsv.calc_import_settingsc           &   C   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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|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d#ddd$dddd%dd&$}i }x t j D ]}|||d' < qBW x\| D ]P\}}|d(d)}|d*d)}	tt |}
||	| d+|	 |
jd,|
jd-||< qbW |S ).ug    Структура сопоставления полей из файла CSV по умолчанию. r"   r&   r'   ext_id)
field_name
model_namerO   
logic_typeZcmf_modified_atZcmf_created_atcmf_modified_bycodetextstatusZ
alarm_dateZdeadlinepriorityzresponsible.namezresponsible.emailzcmf_author.namezcmf_author.emailzexecutors.namezexecutors.emailparent_taskzparent_task.codezchild_tasks.codeZtask_code_prefixactivityactual_workr#   sched_start_datesched_finish_date
sched_workagregat_workactual_myself_workZactual_completeZactual_finish_dater%   )$u/   Ид внешней системы задачиu   Тема задачиu   Тип задачиu(   Дата изменения задачиu&   Дата создания задачиu*   ФИО изменившего задачуu   Код задачиu   Описание задачиu   Статус задачиu   Будильник задачиu$   Крайний срок задачиu   Важностьu   ФИО исполнителяu   Email исполнителяu   ФИО автораu   Email автораu!   ФИО соисполнителяu    Email соисполнителяu%   Родительская задачаu$   Код основной задачиu$   Код дочерней задачиu   Название проектаu   Код проектаu   Префикс задачu   Тип проектаu   Вид деятельностиu   Список задачu/   Фактические трудозатратыu&   Плановая дата началаu,   Плановая дата окончанияu/   Планируемые трудозатратыu2   Сумма дочерних трудозатратui   Фактические трудозатраты по собственным ресурсам задачиu-   Фактический % завершенияu   Дата финишаu   Комментарийr   ri    rh   .T)r   rh   field_qualnamer   requiredverbose_name)r   r"   r    itemsr[   getattrr   r|   )Zname_cmf_taskZname_cmf_projectZname_cmf_epicr`   Zdefault_local_attrs_mappingZshop_frV   Zvalue_modelri   Z	name_attrmodelr   r   r   r]      sl    
z!CmfPluginCsv._default_mapping_csvc             C   s@  g }ddg g d}d}t jj|ddddd	ggd
gd}|sH| jjd | |}|jd rdt| xt	|D ]\}}|dkrP g }	|d 
|	 xzt	|jD ]l\}
}|d sq|d d dd }|s|dkrd}|dkr|dkr|d 
|d d  |	
||
  qW qnW |d r&|
| |s<d|d< d|d< |S )Nu   СделкиZ	handshake)rV   r   titlesrowsFrP   rQ   z.csvz.xlsz.xlsxz-cmf_modified_at)rS   rN   rM   u)   Не найден файл импортаrT   r   r   rX   rz   ry   r   CmfDealT)r   r"   r   r   u   ЗадачиrV   zcalendar-todayr   )r   r\   r[   r   rY   errorr.   rL   nextr/   r^   Zcsv_import_settings_fieldssplit)r   r   resultZdealsZis_dealZattachr7   ra   rb   Zdata_rowrc   r_   ri   r   r   r   preview   sB    




zCmfPluginCsv.preview)	row_arrayr_   r*   c       	      C   s   t  }xt|d d D ]\}}|| s*q|d s6qn|d d |jkrJq|d d d}t||d }t|tjjrt	|dkr|d || i||d < qd|| i||d < q|j
d	kr| || ||d < q|| ||d < qW |S )
Nr   r   rX   r|   rh   ry   r   rg   ro   )dictr/   r|   r   r~   
issubclassZcmfr   Z
CmfRelBaselen
class_nameZcalc_priority)	r   r   r_   r   r(   idxZfield_settingsZfield_partsZfieldr   r   r   _map_object  s$    
zCmfPluginCsv._map_objectc             C   s   d }|  || jjd tj}|rg }dddg}xT|D ]L}||d}|r4|dkrn|d|d|gdd|gg n||d|g P q4W |rtjj|d}|S )	NrU   rg   rl   rO   rx   ORz==)rN   )r   r   rL   r   r&   r[   r^   )r   rb   project_objproject_filteruniq_fields
uniq_fielduniq_field_valuer   r   r   _get_project.  s    

zCmfPluginCsv._get_projectc       
      C   s   d }|  || jjd tj}|rg }dddg}xT|D ]L}||d}|r4|dkrn|d|d|gdd|gg n||d|g P q4W |rtjj|dd	}	|d
d|gdd|	gg tjj|d}|S )NrU   rg   rl   rO   rx   r   z==sprint)tree_parentsys_typerS   r   )rN   )	r   r   rL   r   r'   r[   r^   	CmfFolderextend)
r   rb   r   
sprint_objr   r   r   r   r   sprint_folderr   r   r   _get_sprintC  s"    

zCmfPluginCsv._get_sprintc             C   st   t jjdd|gd}|spt jjdd| gd}t|dkrd| jjd| dt| d	 t	d
|rp|d }|S )Nrl   z==)rN   rO   ILIKEr   u<   Компаний с одинаковым названием z > uF   , укажите код компании вместо названияu]   Найдено несколько компаний с одинаковым названиемr   )
r   r!   r[   liststripr   r   rY   r   r   )r   rg   company	companiesr   r   r   _get_companyZ  s     zCmfPluginCsv._get_company)r   c             C   s   x|D ]}d|d< | j jd|  | | j tj|\}}|j  |rt|j	j
dkrtjjdd|j
gddd	ggd
}|j| |  qW d S )NTZservicedesk_allowu1   Пытаемся создать компанию zproject.servicedesk:defaultzparent.codez==zproject_role.code=zsdesk-client:default)rN   )r   rY   infoprocess_any_table_fieldsr   r!   dpcommitrD   rj   rl   ZCmfProjectRoleAssignr[   membersr^   save)r   r   r   r   Zcompany_objis_newZrole_assignr   r   r   _process_companiesj  s    


zCmfPluginCsv._process_companies)personsc       	      C   s   x|D ]}d }| dr4|d  d}| ||d< | jjd|  | | jtj|\}}|j	  |rt
|jjdkr|jjst
|j}| j|t }|r|jr|jjtjs||jj qW d S )Nr   rg   u9   Пытаемся создать пользователя zproject.servicedesk:default)r[   r   r   rY   r   r   r   r   r   r   rD   rj   rl   Z
user_localr;   rK   person_emails
setdefaultsetZemailendswithr   Z
ORG_DOMAINadd)	r   r   r   personZ
project_idZcompany_ext_idZ
person_objZperson_is_newZproject_person_emailsr   r   r   _process_persons{  s"    



zCmfPluginCsv._process_personsc             C   s,  d|d j  d|d j  }d|d j d|d j }tjjdd|gd	}|s| jjd
 tjjdd|d j	dd  dgd	}|stjjdd}tj||| jd}||_|j
r|  tjj|d d d}|sdd|d d gddd gg}tjj|d	}|s$tj|d d | jd}|d d |_|d}|sN|d d }| |}	|	|_|d d |_|j
r|jdd |j  d|d d  }
tjj|
d}|stjjdd|gdd|ggd	}|stjjdd|d d gdd|ggd	}|s| jjd tj|| j|d}|
|_|d d |_||_|	|_|j
rT|j|j d d|d j  }d |d d  }tjj|d}|stjjd!d}tj||| jd}||_t|d jd"kr||_|j
r|  tjj|d ||d#d$}|s"|d |d#|| jd%}tjf |}|  |||fS )&NzCSV::rS   z::rj   u   БП для проекта u    и типа rg   r   )rN   u/   Не нашли БП, создаем новыйrl   LIKEr+   r   %zdefault.system:default)rl   )rg   templater   rn   )rg   rO   z==)rO   r   cache_status_typeT)save_importworkflowstatus_codeu7   Не нашли статус, создаем новый)r   r   r   )	only_datau%   CSV-схема для проекта zsoftdev:default)ztask.agile:defaultztask.base:defaultr"   )rj   Ztarger_workflow	scheme_wfcmf_model_name)rj   Ztarget_workflowr   r   r   )rK   rO   r   CmfWorkflowr[   r   rY   r   rl   r   
is_changedr   CmfStatusCoderg   Zcalc_status_typestatus_type	CmfStatusr   r   CmfSchemeWfrD   Zdefault_task_workflowZCmfSchemeWfRule)r   taskrg   rO   r   r   Zcmf_status_coder   r   r   status_ext_idtask_statusZscheme_ext_idZscheme_nameZschemeZruleZ	rule_dictr   r   r   _process_workflow  s    *



zCmfPluginCsv._process_workflowc       	      C   s  d }d }d }d }| dr8|d  dr8|d d  }|rtjj ddd| dgd}|s| jjd| d tjj d	d
|gdgd}|s| jjd| d tjj dd|gdgd}|r|jrd| |j |_nd| d|_|jdd |r|d d  }| jjd| d d	d
|gddd gg}tj	j |d}|rldd
|gdd
|gg}tj
j |d}|sdd
|gd	d
|gg}tj
j |d}|s| jjd| d dd
|gdd|gg}tj
j |d}|s| dr| |\}}}n| jjd ||d< ||d< |S )Nr   rg   r   z%::z::%)rN   u   Ищем БП по коду "rA   rl   r   )rN   r   u   Ищем БП по имени "rO   r   z::T)r   rn   u-   Ищем статус в БП по коду "z==r   u/   Ищем статус в БП по имени "rj   ut   Невозможно создать БП и статус, не указан логический тип задачи)r[   r   r   r   r   rY   r   rg   r   r   r   r   Zwarning)	r   r   workflow_schemeZworkflow_ext_idr   r   r   Zfilter_r   r   r   r   _calc_workflow  sV    

zCmfPluginCsv._calc_workflow)projectsc             C   s
  x|  D ]}|d }|ds*d|d< |dsHtjjdd|d< n| |d|d< |dsttjjd	d|d< |d
r| ||d
< | | jtj	|\}}|j
  |r| |d |}|r||_|  | |d | | |d | | |d | qW d S )NdataZproject_typer   rj   zproject.agile:default)rl   r&   r   zsoftdev:defaultrq   	workflowssprintsr   r   )valuesr[   r   CmfLogicType_process_logic_typer   _process_activityr   r   r&   r   r   _process_workflowsr   r   _process_sprintsr   r   )r   r   r   project_datar   r   r   r   r   r   _process_projects  s*    




zCmfPluginCsv._process_projectsc             C   sh   t jjdd}xT|D ]L}t jj|dd}||d< ||d< ||d< | | jt j|\}}|j  qW d S )Nzlist.agile_sprint:default)rl   r   )r   r   rS   r   rj   )	r   r   r[   r   r   r   r'   r   r   )r   r   r   Zsprint_logic_typer   r   r   r   r   r   r   r   6  s    
zCmfPluginCsv._process_sprintsc             C   sL   d }xB|D ]:}||d< | dr0| |d|d< | dr
| |}q
W |S )NrS   rj   r"   rn   )r[   r   r   )r   r   r   r   r   r   r   r   r   @  s    


zCmfPluginCsv._process_workflowsc          	   C   s|  |  || jjd tj}|rxy|dr4d|d< |drFd|d< x*dD ]"}||rLt|| d ||< qLW |d	d
 |D  x |D ]}t|j	j
|||  qW |ds |dddg |j	jr |j	jr |j	j|j	j }| d d d }tt|d d}|d d |j	_|j	j
jdd W nD tk
rv   t  | jjd| d|  |  jd7  _Y nX d S )NrU   Zconstrain_start_datez0-constZconstrain_start_typeZconstrain_finish_dateZconstrain_finish_type)ru   Z
const_workrv   rr   rw   <   c             S   s   g | ]}d | qS )zop_gantt_task.r   )r<   keyr   r   r   r>   Y  s    z/CmfPluginCsv._process_gantt.<locals>.<listcomp>sched_durationzop_gantt_task.sched_start_datez(task_obj.op_gantt_task.sched_finish_datezop_gantt_task.sched_duration   g&?r      T)r   u:   Не удалось импортировать Гантт u    для задачи )r   r   rL   r   r#   r[   floatZload_fieldssetattrZop_gantt_taskr;   rs   rt   Ztotal_secondsmaxmathZceilr   r   r   commit_with_eventrY   r1   _has_errors)r   rb   task_objZganttr   ZdeltaZ
delta_daysZ	work_daysr   r   r   _process_ganttM  s4    





zCmfPluginCsv._process_ganttc             C   sl  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
ddddddddddddddddddddd}| j jd|d   |d d|d d }||}|r.tjjdd|d gdgd}|jr||jkrd| |j |_nd| d|_|jr*|j	dd |S tjjddd | d!gd"}|rT|S | j jd#| d$ tjjdd|gdgd}|stjjdd%|gdgd}|r|jr||jkrd| |j |_nd| d|_|jr|j	dd |S | j jd& |d'krd}n|d(kr d}tjjdd|gd"}t
d| d|||d)}	| | j tj|	\}}
t  |S )*Nu   Подзадачаztask.sub:default)rO   rl   Z	UserStoryztask.userstory:defaultz
Task Agileztask.agile:defaultu   Задачаztask.base:defaultBugztask.bug:defaultEpicztask.epic:defaultu&   Проект. Классическийzproject.base:defaultu   Проект. Agilezproject.agile:defaultu   Проект. Service Deskzproject.servicedesk:default)zSub-taskZSubtasku   ПодзадачаZStoryu   ИсторияZTasku   Задачаr   u   Багu   Эпикr   u   КлассическийZAgilezService DeskZServiceDesku   Логический тип rj   rg   rO   rl   z==)rN   r   z::T)r   r   z%::z::%)rN   uF   Ищем логический тип по коду или имени ''r   uF   Не нашли, создаем новый логический типr"   r&   )rg   rO   r   r   )r   rY   r   r[   r   r   r   rg   r   r   r   r   r   )r   objri   	name2coderg   Zlogic_type_dictrj   Ztemplate_coder   Zlogic_type_paramsr   r   r   r   r   m  sr    



z CmfPluginCsv._process_logic_typec             C   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ddd	}| j jd|d   |d d|d d}||}|rtjjdd|d gdgd}|jr||jkrd| |j |_nd| d|_|jr|jdd |S tjjddd | d!gd"}|r|S | j jd#| d$ tjjdd|	 gdgd}|sltjjdd%|	 gdgd}|r|jr||jkrd| |j |_nd| d|_|jr|jdd |S | j jd& t
d| d|	 d'}| | j tj|\}}t  |S )(u"    Виды деятельностиu   БизнесZbusiness)rO   rl   u   ПродажиZsalesu   МаркетингZ	marketingu   ПроизводствоZ
productionu   ПоддержкаZhelpdesku   БухгалтерияZfinanceu!   ИТ инфраструктураZservicedesku%   Хозяйственная частьZ	householdu   Разработка ПОZsoftdev)	u   Бизнесu   Продажиu   Маркетингu   Производствоu   Поддержкаu   Бухгалтерияu!   ИТ инфраструктураu%   Хозяйственная частьu   Разработка ПОu    Вид деятельности rq   rg   rO   rl   z==)rN   r   z::T)r   r   z%::z::%)rN   uJ   Ищем вид деятельности по коду или имени 'r   r   uJ   Не нашли, создаем новый вид деятельности)rg   rO   )r   rY   r   r[   r   ZCmfActivityrg   r   r   r   r   r   r   )r   r   r   rg   Zactivity_dictrq   Zactivity_paramsr   r   r   r   r     sV    


zCmfPluginCsv._process_activityc          
   C   s  | j jd t| j}d}t }xB| jD ]6}| j  rBd S | j j| d|  |d7 }ddd|gdd|gg}tj	j
|d}|s| j jd	|  |  jd7  _q.x| j| D ]}yjddd|gdd|gg}tj	j
|d
ddgd}	||	_|	jjds|	jjdr|	j|	_|	jdd W q tk
r`   | j jd|  |  jd7  _Y qX qW q.W t | }
| j jd|
dd d S )Nu5   Привяжем подзадачи к задачамr   u    из r   rg   z==rl   )rN   uE   Не удалось найти родительскую задачу rp   r   rj   )rN   r   ztask.subprojectz	task.epicT)r   u4   Не удалось привязать задачу u<   Обработка подзадач выполнена за z.3fu    сек.)r   rY   r   r   subtaskstime	monotonic	is_cancelr   r"   r[   r   r   rp   rj   rl   
startswithr   r   r   r1   )r   totalra   t1parent_ext_idr   rp   Zchild_ext_idZ_filter_childr   t2r   r   r   _process_subtasks  s:    

zCmfPluginCsv._process_subtasksc       
      C   s  | j jd t| j}d}t }x| jD ]}yR| j  rFd S | j j| d|  |d7 }tj	j
|d d}|stj	j
dd|d gd}|s| j jd	|d  d
 |  jd7  _w.tjj
dd|d gd}|s| j jd|d   |  jd7  _w.tjj
dd|d gd}|sN| j jd|d   |  jd7  _w.tjj
|||d}|stj|||| j d}|jdd W q.   | j jd|  |  jd7  _Y q.X q.W t | }	| j jd|	dd d S )Nu&   Создадим связи задачr   u    из type)rl   rO   r   )rN   u2   Не удалось найти тип связи "rA   rg   in_linku=   Не удалось найти входящую задачу out_linku?   Не удалось найти исходящую задачу )relation_typer   r   )r   r   r   r   T)r   u.   Не удалось создать связь u8   Обработка связей выполнена за z.3fu    сек.)r   rY   r   r   	relationsr   r   r   r   ZCmfRelationTyper[   r   r   r"   CmfRelationOptionr   r1   )
r   r   ra   r   relation_datar   r   r   Zrelation_optionr   r   r   r   _process_relations	  sV    


zCmfPluginCsv._process_relationsc             C   s   |  || jjd tj}|r| jjd|  d|d< | j|d< |drftjj|d d d|d< |d	rtj	j|d	 d d
|d	< tjf |}|j
r|jr|j
jtj|jjd |_|jdd d S )NrU   u   Грузим журнал closedrn   r   
cmf_authorrg   )loginrS   )rg   )ZminutesT)r   )r   r   rL   r   r$   rY   r   r[   r   r"   Z
start_dateZ
time_spentr;   datetimeZ	timedeltaZend_dater   )r   rb   Ztimetracker_historyhistoryr   r   r   _process_timetracker@  s"    



z!CmfPluginCsv._process_timetracker
      )Z	max_triesZmax_timec             C   s<  | j jd }| ||tj}| |}|r|r|dsDtd||d< |drf| |d|d< |drz| 	| |dr|d |d	< |d	r|ds|d	= xRd
D ]J}||}|r|drtj
j|d d}ntj
jf |}|r|||< qW | j d|  dd| j jgdddgdd|d gg}| j jjdd }	|drhd}	dd|d g}n.|drd}	ddd|d gdd|d gg}| j| j tj|||	d\}
}|r<tjd| jj d| jj d| j j dd|
| j d}|jdd |j  | j d|
 d|d d |d d!|d d"	 n8| j d#|
 d|d d |d d!|d d"	 | ||
 | ||}|r|
j  |
j| |
jr|
jdd |
j  | ||tj}|r"|
|d< | | j tj|\}}n&|r"| j jd$tjd% |  jd&7  _|  | | j j  d S )'NrU   rO   u:   Не указано наименование задачи!rS   rj   r"   rn   epicrp   )r   Z	cmf_ownerrk   ZresponsibleZwaiting_forrg   )r   u_   Пытаемся создать или обновить задачу по параметрам zcmf_import.pluginz==Zimport_originalTZmerge_identic_namesFrl   r   )Z
filter_objdont_updateuB   Задача импортирована из файла: <a href="z" target="_blank">z</a> ()   )rm   Z	log_levelrS   r   )r   u'   Создали новую задачу z ext_id=z code=z name='r   u   Нашли задачу u   Невозможно импортировать задачу без проекта, создайте проект и укажите ID в файле)levelr   )!r   rL   r   r   r"   r   r[   r   r   r   r   r   pluginr;   r   r%   import_filerR   rO   rl   r   r   r   r   r   Zlistsloadr^   r   loggingZERRORr   r  )r   rb   rU   r   r   r   rd   r   r   r  r   Ztask_is_newcommentr   Zcomment_objZcomment_is_newr   r   r   _process_taskY  s    








"

42



zCmfPluginCsv._process_taskc             C   s   t dd x| j rP | \}}|d kr>|||f P y(| jjd| d|  | | W q tk
r } z>|  j	d7  _	| jj
d| d| d|  | jj  W d d }~X Y qX qW W d Q R X d S )	NF)Zinit_views_and_dsu   Импорт строки u    из r   u<   Не удалось импортировать строку z: z. )r	   r   r   r[   putrY   r   r  r   r   r1   r   Zrollback)r   	row_queue
total_rowsZrow_numZrow_dataexcr   r   r   _process_task_worker  s    
 z!CmfPluginCsv._process_task_workerc          
   C   s  ddl m} t p t Z tjj|dgd}|| _tj	j|ddddd	ggd
gdgd| _
tdd | | j
D }tjdd}g }xZt| jD ]L}	tj| jd|	d  ||dd}
||
 |
  | jjd|
  qW xlt| | j
D ]X\}	}| j rP |jd r(|	dkr(q|	|k r4q|	|kr@P ||	d |f qW |d x|D ]}
|
  qfW W d Q R X W d Q R X | jS )Nr   )r	   r   )rK   r   rP   rQ   z.csvz.xlsz.xlsxz-cmf_modified_atrR   )rS   rN   rM   r   c             S   s   g | ]}d qS )r   r   )r<   r8   r   r   r   r>     s    z2CmfPluginCsv.process_task_fork.<locals>.<listcomp>i  )maxsizez_process_task_worker r   )r  r  )targetrO   kwargsu.   Параллельный обработчик rT   )NN)cmf.appr	   ZcmfutilZdisable_aclZdisable_notifyr   rZ   r[   r   r\   r
  r   r.   queueZQueuerangeZthreading_max_forks	threadingZThreadr  r^   startrY   r   r/   r   rL   r  joinr   )r   Zcmf_import_idstart_index	end_indexr	   r   r  r  Zthreadsra   Zthreadrb   r   r   r   process_task_fork  sF    




"zCmfPluginCsv.process_task_forkc             C   s   dd l }|jdddd| jjj d| jj d| d| d		gd
d
tddtddd}| jd|j d| d|  | j  |S )Nr   z/usr/bin/python3z	manage.pyshellz%plugin = models.CmfPluginCsv.get(id="z'");retcode = plugin.process_task_fork("z", z, z);Tz"/var/log/eva-import-subprocess.logza+z&/var/log/eva-import-subprocess.err.log)Z	close_fdsZstart_new_sessionstdoutstderru,   Запустили подпроцесс PID u)    для обработки строк с u    по )	
subprocessPopenr   r	  rK   rG   r   pidZ
log_detail)r   r  r  r#  procr   r   r   _execute_task  s    ( 
zCmfPluginCsv._execute_taskc             C   s   | j }tdd | | jD }|| }|| }t }g }xTt|D ]H}|| }|| }	|d |k rp|	d8 }	n|	|7 }	| ||	}
||
 qFW x*|D ]"}
|
	  |
j
r|  j|
j
7  _qW t | }| jjd|dd d S )Nc             S   s   g | ]}d qS )r   r   )r<   r8   r   r   r   r>   (  s    z/CmfPluginCsv._process_tasks.<locals>.<listcomp>r   u.   Импорт задач выполнен за z.3fu    сек.)r   r   r.   r
  r   r   r  r'  r^   Zcommunicate
returncoder   r   rY   r   )r   r   r  Z
chunk_sizeZ	remainderr   Z	processesra   r  r  r&  r   r   r   r   _process_tasks%  s(    

zCmfPluginCsv._process_tasksc             C   sX  | j jd }xDt| | jD ].\}}| j  r6P | j jd rL|dkrLq | ||tj}| ||tj	}| ||tj
}|rdddg}x4|D ],}||d}	|	r| j|	i }
||
d< P qW |
d	g }| ||tj}|r||kr|| ||
d	< |
d
g }| ||tj}|r|d}|s6|d }|drN|d |d< |d}|r|ds|d= |d}|s|d }| j|g }|| || j|< | ||tj}|rd}|dr|d d }|dr.|d d }x8|dD ]*}|||d}|| jkr | j| q W |dr|d d }x8|dD ]*}|||d}|| jkrR| j| qRW |d|d|dd}||kr|| ||
d
< |
dg }|r||kr|| ||
d< |
dg }|r||kr|| ||
d< q |r6|| jkr6| j| |r || jkr | j| q W dS )u   
        Из строк файла собирает данные проектов, спринтов, БП, компаний и пользователей для последующего импорта
        rU   rT   r   rg   rl   rO   rx   r   r   r   r  rp   zsystem.finish:startr   r   r@   )r   r   r   r   r   rn   rj   )r   rn   rj   r   r   N)r   rL   r/   r.   r
  r   r   r   r!   r   r&   r[   r   r   r'   r^   r"   r   r   r   r   r   r   )r   rU   ra   rb   Zcompany_dataZperson_datar   r   r   r   r   Zproject_sprintsZsprint_dataZproject_workflowsr   Ztask_ext_idrp   r   r   r   r   Zrelated_tasksZrelated_taskZrelationr   Zproject_companiesZproject_personsr   r   r   _prepare_import_dataC  s    













z!CmfPluginCsv._prepare_import_datac             C   sF  || _ |   g | _g | _i | _i | _i | _g | _tj	j
|dddddggdgdgd| _|   | | j | | j | | j |   |   |   | j jj
d	d
r"xp| j D ]b\}}|sq| j jdt| d|  |rtjjj|t|gd qtjjjt|gd qW | jr>| j d| j  | j S )NrP   rQ   z.csvz.xlsz.xlsxz-cmf_modified_atrR   )rS   rN   rM   r   Zsend_invitesTu,   Отправляем приглашения u    пользователям: )argsu#   Ошибок обнаружено: ) r   r   r   r   r   r   r   r   r   r\   r[   r
  r*  r   r   r   r)  r   r   rL   r;   r}   rY   r   r   r   Zregister_sdesk_clientZapply_asyncr   Zregister_personsr   r   )r   r   r   r   r   r   r   process_import  s>    zCmfPluginCsv.process_import)N)N)Nr   )2__name__
__module____qualname__r   r  ZgetLoggerClass__annotations__r   r   staticmethodr)   boolr:   r   r   r.   rf   r   rD   r]   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  backoffZon_exceptionZexpor   r  r  r  r'  r)  r*  r,  r   r   r   r   r
      sL   
=?%L>
 B8"7o
3hr
   )rF   r   copyr   r   Zpathlibr   typingr   r   r3  r   r  r  r   r   rE   rC   r   Zcmf.includeZmodules.settings.fieldsr   r  r	   r
   r   r   r   r   <module>   s$   