U
    g0                    @   s   d dl Z d dlZd dlmZ d dl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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)ParserError)*)cmf_plugin_csvcmf_contextc                   @   s  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e	eedddZdd ZeeedddZdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Z d+d, Z!d-d. Z"dmed/d0d1Z#dned2d3d4Z$d5d6 Z%d7d8 Z&ed9d:d;Z'd<d= Z(d>d? Z)d@dA Z*dBdC Z+dDdE Z,dFdG Z-dHdI Z.dJdK Z/e0j1e0j2e3dLdMdNdOdP Z4dQdR Z5dodSdTZ6dUdV Z7dWdX Z8dYdZ Z9i dfd[d\Z:d]d^ Z;d_d` Z<dadb Z=dcdd Z>dedf Z?dgdh Z@didj ZAdkdl ZBdS )p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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   Поля группu   Поля активовu   Поля локаций)models	CmfPersonimport_shop_fieldsr   
CmfCompanyCmfTaskCmfGanttTaskCmfTimeTrackerHistoryZCmfTimeTracker
CmfComment
CmfProjectCmfListCmfPersonGroupCmfAssetCmfLocation)resr   r   r   calc_models_settings8   sB    









z!CmfPluginCsv.calc_models_settings)returnc              	   C   s   |j }d}d}z | |}t|D ]\}}q"W n tk
rn   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)abort*   Приложен пустой файл 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_fileT   s&    

zCmfPluginCsv._check_filec              	   c   s   t | j}|jdkrLtt|}|d}| D ]}dd |D V  q4n~|jdkrt	t|}|j
}|jddD ]
}|V  qvnF|jdkrtd	 t|d
"}tj|dddD ]
}|V  qW 5 Q R X d S )N.xlsr   c                 S   s   g | ]
}|j qS r   )value).0itemr   r   r   
<listcomp>p   s     z*CmfPluginCsv._get_file.<locals>.<listcomp>.xlsxT)Zvalues_only.csvi r;")Z	delimiterZ	quotechar)r   r3   suffixxlrdZopen_workbookstrZsheet_by_indexZget_rowsopenpyxlZload_workbookZactiveZ	iter_rowscsvZfield_size_limitopenreader)r;   Zattachment_file_pathZworkbookZ	worksheetelfiler   r   r   r4   i   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 | 	|}| 
 }t|D ]j\}}	|dkr|jd s qn|dkr qt|	D ].\}
}d}t|tjr|d}|dkr|r|jd rt|jd D ]}d|kr0d|kr0 q|d dkrBq|d D ]J}|d |krJ|d }|r| |d s|d | d} qqJq|s|d |d d d d q|d |
 }||d }||d< |r||d< |d |d< qq|d s| jd g S |gS )N-cmf_modified_atidz!=json_settings)order_byfilterr   ZCSVnamer   	file_typeINrG   rA   rF   urlparentrX   rW   r   r   	first_rowr   Fz%Y-%m-%d %H:%M:%Simport_settingsrZ   r   titlemodel_fieldfield_qualnameT)rb   file_valrc   r   re   r   r2   )loggerr   Zattachmentsr    	CmfImportgetrU   CmfAttachmentr@   r4   _default_mapping_csvr5   rV   
isinstancedatetimestrftimer   _is_backref_fieldappendr7   )r   r   Zprev_settingssettingsr;   r<   r=   default_mappingirowjvalfoundZprev_setZ
prev_fieldrc   Zrow_settingsr   r   r   calc_import_settings}   sp    




 

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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 }tj D ]}|||d/ < q| D ]P\}}|d0d1}|d2d1}	tt|}
||	| d3|	 |
jd4|
jd5||< q|S )6ug    Структура сопоставления полей из файла CSV по умолчанию. r$   r(   r)   ext_id)
field_name
model_namerZ   
logic_typeZcmf_modified_at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task_code_prefixactivityactual_workr%   sched_start_datesched_finish_date
sched_workagregat_workactual_myself_workactual_completeactual_finish_dateoutline_numberr'   )$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/   Планируемые трудозатратыu2   Сумма дочерних трудозатратui   Фактические трудозатраты по собственным ресурсам задачиu-   Фактический % завершенияu   Дата финишаu]   Структурный номер (для поиска родительской задачи)u   Комментарийsched_durationin_linkCmfRelationOptionactual_start_dateconstrain_start_typeconstrain_start_dateis_milestone)u   СДРu   ИДu   Название_задачиu   Длительностьu   Предшественникиu   Дата_началаu   Дата_окончанияu#   Процент_завершенияu#   Фактическое_началоu)   Фактическое_окончаниеu   Тип_ограниченияu   Дата_ограниченияu   Дата_созданияu7   Запланированные_трудозатратыu/   Фактические_трудозатратыu   Вехаr   rz    ry   .T)r   ry   rd   r   requiredverbose_name)	updater    r$   r"   itemsrh   getattrr   r   )Zname_cmf_taskZname_cmf_projectZname_cmf_epicrq   Zdefault_local_attrs_mappingZshop_frb   Zvalue_modelrz   Z	name_attrmodelr   r   r   rj      s    ',
z!CmfPluginCsv._default_mapping_csv)rd   r/   c                 C   sd   |  d^}}t|}|D ]B}t||}t|tjjr> dS t|drN|j	sR q`t|j	}qdS )Nr   Tr   F)
splitcmfutilZget_model_by_namer   
issubclasscmfr   Z
CmfBackrefhasattrr   )rd   rz   Zattrsr   attrfieldr   r   r   rn   .  s    

zCmfPluginCsv._is_backref_fieldc                 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| t	|D ]\}}|dkr qg }	|d 
|	 t	|jD ]l\}
}|d sq|d d dd }|s|dkrd}|dkr|dkr|d 
|d d  |	
||
  qql|d r"|
| |s8d|d< d|d< |S )Nu   СделкиZ	handshake)rb   r   titlesrowsFr[   r\   rG   rA   rF   rT   )r_   rX   rW   u)   Не найден файл импортаr`   r   r   rc   rd   r   r   CmfDealT)r   r$   r   r   u   Задачиrb   zcalendar-todayr   )r    ri   rh   r   rf   errorr4   rV   nextr5   ro   Zcsv_import_settings_fieldsr   )r   r   resultZdealsZis_dealZattachr=   rr   rs   Zdata_rowrt   rp   rz   r   r   r   preview@  sD    



zCmfPluginCsv.preview)	row_arrayrp   r/   c                 C   sb  t  }t|d 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 < nd|| i||d < q|j
d	kr| || ||d < qt|tjjrL||  }	d
ddddh}
dddddh}|	|
kr&d||d < n$|	|kr>d||d < nd ||d < q|| ||d < q|S )Nr   r   rc   r   ry   r   r   rx   r   u   даtrueZyes1+   нетZfalseno0-TF)dictr5   r   r   r   r   r   r   Z
CmfRelBaselen
class_nameZcalc_priorityZCmfBoollower)r   r   rp   r   r-   idxZfield_settingsZfield_partsr   rB   Ztrue_valuesZfalse_valuesr   r   r   _map_objecte  s6    


zCmfPluginCsv._map_objectc                 C   s   d }|  || jjd tj}|rg }dddg}|D ]N}||d}|r2|dkrl|d|d|gdd|gg n||d|g  qq2|rtjj|d}|S )	Nra   rx   r~   rZ   r   OR==rX   )r   r   rV   r    r(   rh   ro   )r   rs   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}|D ]N}||d}|r2|dkrl|d|d|gdd|gg n||d|g  qq2|rtjj|dd	}	|d
d|gdd|	gg tjj|d}|S )Nra   rx   r~   rZ   r   r   r   sprinttree_parentZsys_typer_   r   r   )	r   r   rV   r    r)   rh   ro   	CmfFolderextend)
r   rs   r   
sprint_objr   r   r   r   r   sprint_folderr   r   r   _get_sprint  s"    
zCmfPluginCsv._get_sprintc                 C   sx   t jjdd|gd}|stt jjdd| gd}t|dkrh| jjd| dt| d	d
dd td|rt|d }|S )Nr~   r   r   rZ   ILIKEr   u<   Компаний с одинаковым названием z > uF   , укажите код компании вместо названияzERR-0071r#   Zobj_typeu]   Найдено несколько компаний с одинаковым названиемr   )	r    r#   rh   liststripr   r   	log_errorr   )r   rx   company	companiesr   r   r   _get_company  s    zCmfPluginCsv._get_companyc                 C   s   d }|rg }dddg}|D ]V}| |d }|r|dkrX|d|d|gdd|gg n||d| g  qrq|rtjj |d}|std| d	n"tjj d
ddgd}| jj	d |S )Nrx   r~   asset_code_prefixr   r   =r   u/   Не найдена схема активов "uf   ", создайте схему и укажите префикс кода активов в файле.systemTu   Не указана схема активов. Установлена схема активов по-умолчанию (системная))
rh   r   ro   upperr    CmfAssetSchemer   r   rf   warning)r   asset_schemeasset_scheme_objr   r   r   r   r   r   r   _get_asset_scheme  s,    

zCmfPluginCsv._get_asset_schemec                 C   s   d }|r| dp$| dp$| d}|rp| }tjj dd|gdddd| dgdd|gdd	|gggdgd
}|std| d| d|S )Nrx   r~   rZ   r_   r   r   LIKE%r   rX   r   u1   Не найдена группа активов "u   " в схеме uY   , создайте группу и укажите ID, код или имя в файле.)rh   r   r    CmfAssetCatr   )r   	asset_catr   asset_cat_objr   r   r   r   _get_asset_cat  s(    	zCmfPluginCsv._get_asset_catc                 C   s   d }|rg }dddg}|D ]R}| |d }|r|dkrX|d|d|gdd|gg n||d|g  qnq|r|dd|g tjj |d}|S 	Nrx   r~   rZ   r   r   r   r_   r   )rh   r   ro   r    CmfAssetType)r   
asset_typer   asset_type_objr   r   r   r   r   r   r   _get_asset_type  s(    
zCmfPluginCsv._get_asset_typec                 C   s   d }|rg }dddg}|D ]R}| |d }|r|dkrX|d|d|gdd|gg n||d|g  qnq|r|dd|g tjj |d}|S r   )rh   r   ro   r    CmfAssetTypeCat)r   asset_type_catr   asset_type_cat_objr   r   r   r   r   r   r   _get_asset_type_cat  s(    
z CmfPluginCsv._get_asset_type_catc           	   	   C   s   t jj|}|j}|s|S |j}dd | D }|  }||}|s||krdd |	 D }t
d| d|j dd| |p|p|S )	Nc                 S   s   i | ]\}}|  |qS r   )r   )rC   kvr   r   r   
<dictcomp>?  s    z9CmfPluginCsv._get_asset_field_choises.<locals>.<dictcomp>c                 S   s   g | ]}d | d qS rJ   r   )rC   r   r   r   r   rE   G  s     z9CmfPluginCsv._get_asset_field_choises.<locals>.<listcomp>u&   Не найдено значение "u
   " для "u2   ". Укажите одно из значений: , )r    r+   r   rh   defaultchoicesr   r   r   valuesr   r   join)	r   ry   rB   r   Zfield_defaultZfield_choisesr   Zfield_valuer   r   r   r   _get_asset_field_choises7  s     
z%CmfPluginCsv._get_asset_field_choisesc                 C   s   d }|r| dr|d  }tjj dddd| dgdd|gdd|gdd|ggd	}|stjj dddd| dgd
d|gdd|ggd	}|s| jjd| dddd |S )Nrx   r   r   r   loginr   emailrZ   r   r~   r   u7   Не найдена группа владельцев "rJ   zERR-0085r+   r   )rh   r   r    r!   r*   r   r   )r   responsibleZresponsible_objZresponsible_ext_idr   r   r   _get_asset_responsibleO  s4    		
z#CmfPluginCsv._get_asset_responsiblec              	   C   s   g }|r| dr|d }|dD ]}| }tjj dddd| dgdd|gdd|gd	d|ggd
}|stjj dddd| dgdd|gd	d|ggd
}|s| jjd| dddd q$|| q$|S )Nrx   rI   r   r   r   r   r   r   rZ   r   r~   r   u5   Не найдена группа поддержки "rJ   zERR-0086r+   r   )	rh   r   r   r    r!   r*   r   r   ro   )r   Zsupport_group_datasupport_group_objsZsupport_groupssupport_groupZsupport_group_ext_idZsupport_group_objr   r   r   _get_asset_support_groupp  s:    		
z%CmfPluginCsv._get_asset_support_groupc                 C   sp   d }|rl| drl|d  }tjj dddd| dgdd|gdd|ggd	}|sl| jjd
| dddd |S )Nrx   r   r   r   r~   r   rZ   r   r   u/   Не найдена локация/адрес "rJ   zERR-0087r+   r   )rh   r   r    r,   r   r   )r   locationZlocation_objZlocation_ext_idr   r   r   _get_asset_location  s"    	
z CmfPluginCsv._get_asset_location)r   c                 C   s   |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d S )NTZservicedesk_allowu1   Пытаемся создать компанию project.servicedesk:defaultzparent.coder   zproject_role.coder   zsdesk-client:defaultr   )r   rf   infoprocess_any_table_fieldsr    r#   dpcommitrM   r{   r~   ZCmfProjectRoleAssignrh   membersro   save)r   r   r   r   Zcompany_objis_newZrole_assignr   r   r   _process_companies  s    

zCmfPluginCsv._process_companies)personsc           	      C   s   |D ]}d }| dr2|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d S )Nr   rx   u9   Пытаемся создать пользователя r   )rh   r   r   rf   r   r   r    r!   r  r  rM   r{   r~   Z
user_localrB   rU   person_emails
setdefaultsetr   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d}||_|j
r|jdd 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 |_|d}|sV|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 d |_||_|	|_|j
rZ|jdd d|d j  }d|d d  }tjj|d}|stjjd d}tj||| jdd}||_t|d jd!kr||_|j
r|jdd tjj|d ||d"d#}|s4|d |d"|| jdd$}tjf |}|jdd |||fS )%NzCSV::r_   ::r{   u   БП для проекта u    и типа rx   r   r   u/   Не нашли БП, создаем новыйr~   r   r0   r   r   zdefault.system:defaultr~   T)rx   templater   import_originalZsave_importr   rx   rZ   r   )rZ   r   r  cache_status_typeworkflowstatus_codeu7   Не нашли статус, создаем новый)r  r   r  r  u%   CSV-схема для проекта softdev:default)task.agile:defaulttask.base:defaultr$   )r{   Ztarger_workflow	scheme_wfcmf_model_name)r{   Ztarget_workflowr  r  r   r  )rU   rZ   r    CmfWorkflowrh   r   rf   r   r~   r   
is_changedr  CmfStatusCoderx   Zcalc_status_typestatus_type	CmfStatusr  CmfSchemeWfrM   Zdefault_task_workflowZCmfSchemeWfRule)r   taskrx   rZ   r  r  Zcmf_status_coder   r  r   status_ext_idtask_statusZscheme_ext_idZscheme_name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  rx   r   %::::%r   u   Ищем БП по коду "rJ   r~   r   r   u   Ищем БП по имени "rZ   r   r  Tr  r   u-   Ищем статус в БП по коду "r   r  u/   Ищем статус в БП по имени "r{   ut   Невозможно создать БП и статус, не указан логический тип задачи)rh   r   r    r  r   rf   r   rx   r  r  r!  r'  r   )	r   r#  workflow_schemeZworkflow_ext_idr  r%  r$  Zfilter_r  r   r   r   _calc_workflow7  sZ    zCmfPluginCsv._calc_workflow)projectsc                 C   s  |  D ]}|d }|ds(d|d< |dsFtjjdd|d< n| |d|d< |dsrtjjd	d|d< |d
r| ||d
< | | jtj	|\}}|j
  |r| |d |}|r||_|  | |d | | |d | | |d | | j|j jj qd S )NdataZproject_typer   r{   project.agile:defaultr  r(   r  r  r   	workflowssprintsr   r  )r   rh   r    CmfLogicType_process_logic_typer"  _process_activityr   r   r(   r  r  _process_workflowsr  r  _process_sprintsr  r  gantt_project_idsr  Zmain_gantt_projectloadrU   rB   )r   r,  r   project_datar   r  r*  r   r   r   _process_projectsu  s,    




zCmfPluginCsv._process_projectsc                 C   sd   t jjdd}|D ]L}t jj|dd}||d< ||d< ||d< | | jt j|\}}|j  qd S )Nzlist.agile_sprint:defaultr  r   r   r_   r   r{   )	r    r1  rh   r   r   r   r)   r  r  )r   r0  r   Zsprint_logic_typer   r   r   r  r   r   r   r5    s    zCmfPluginCsv._process_sprintsc                 C   sH   d }|D ]:}||d< | dr.| |d|d< | dr| |}q|S )Nr_   r{   r$   r   )rh   r2  r+  )r   r/  r   r*  r  r   r   r   r4    s    

zCmfPluginCsv._process_workflowsc                 C   s  |  || jjd tj}d|kr&|d= |rƐz@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rp|d}|d   }||}|dkr||d< n|dkrd|d< d |d< ||d< ||d< n|dkr|dkr||d< n d|d< d |d< ||d< ||d< nRd|d< dd tjjj	
 D }	| jjd| dd|	 ddd |  jd7  _|dr |d dkr |d   }
||
|d< |d dkr dd tjjj	
 D }	| jjd|
 dd|	 ddd |  jd7  _d D ]R}||r||d!r@||d d"  ||< t|| d# ||< qd$D ]}||r\||  d%r||= q\|| d&s|| d's|| d(r\|| d)d* d+d,}t|d- d# ||< q\|d.d |D  d/D ]}||ks|| s q|| }d0d1d2d3d4d5d6d7d8d9d:d;d<}| D ]2\}}|| krN| ||||<  qqN|d=krd ||< qd>D ]:}||ks|| sq|| }tt|}|||< q|D ]}t|jj|||  q|d?s^|d@dAdBdCg |jjr^|jjr^tjj|j |jjj|jjj|jjjdD}||j_|jj dEdF W nV t!k
r } z6t"  | jjdG| dH| dIdd |  jd7  _W 5 d }~X Y nX d S )JNra   r   0-const1-early2-latter3-after4-before2-before1-after)   фиксированнаяu   как можно раньшеu   как можно позже   не раньше   не позжеu    начало не позднееu   начало не ранее&   окончание не позднее"   окончание не ранее'   фиксированное начало-   фиксированное окончание   фн   фоu   кмрu   кмпu   ннрu   ннп   онр   онп)	u   фиксированныйrB  rC  rG  rE  rD  rI  rJ  rK  r   r   )r;  r<  r=  r>  )r@  r?  constrain_finish_typeconstrain_finish_date)rA  rF  rH  c                 S   s   g | ]}d | d qS r   r   rC   tr   r   r   rE     s     z/CmfPluginCsv._process_gantt.<locals>.<listcomp>uG   Не найден тип ограничения даты начала "u,   ". Укажите один из типов: r   zERR-0082r%   r   r   )r:  r@  r?  c                 S   s   g | ]}d | d qS r   r   rN  r   r   r   rE     s     uM   Не найден тип ограничения даты окончания "zERR-0083)r   Z
const_workr   r   r      ч<   )r   ?   дu   днейu   день r   ,r      c                 S   s   g | ]}d | qS )zop_gantt_task.r   )rC   keyr   r   r   rE     s     )r   r   r   r   r   rM  ZjanZfebZmarZaprZmayZjunZjulZaugsepoctZnovZdec)u   январьu   февральu   мартu   апрельu   майu   июньu   июльu   августu   сентябрьu   октябрьu   ноябрьu   декабрьu   НД)r   r   zop_gantt_task.sched_start_datezop_gantt_task.sched_finish_datezop_gantt_task.sched_durationzop_gantt_task.is_manual)ZcalendarZfrom_dtZto_dtZforce_include_endsTZfrom_importu:   Не удалось импортировать Гантт u    для задачи zERR-0072)#r   r   rV   r    r%   rh   r   r   r   r   r   r   r   _has_errorsrL  r  floatr   replaceZload_fieldsr   r   setattrop_gantt_taskrB   r   r   ZCmfCalendarZget_duration_minutesZ_get_calendarZ	is_manualr   check_gantt_projectr   commit_with_event)r   rs   task_objganttZconstrain_start_type_mappingZconstrain_finish_type_mappingr   Zconstrain_start_type_rawr   typesZconstrain_finish_type_rawrX  ru   Z_vmappingZmonth_ruZmonth_enZcalendar_durationer   r   r   _process_gantt  s"   







0

zCmfPluginCsv._process_ganttc                 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krdnd}| j jd||   || d|| d  }||}|rVtjjd!d"|d! gdgd#}|jr0||jkr>d$| |j |_nd$| d$|_|jrR|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#}|stjjd d-|gdgd#}|r|jr||jkrd$| |j |_nd$| d$|_|jr|j	d%d& |S | j jd. |d/kr:d}n|d0krJd}n|d1krXd}tjjd!d"|gd*}	t
d$| d$|||	d2}
| | j tj|
\}}t  |S )3N   Подзадачаztask.sub:defaultrZ   r~   Z	UserStoryztask.userstory:defaultz
Task Agiler     Задачаr  Bugztask.bug:defaultEpicztask.epic:defaultu&   Проект. Классическийzproject.base:defaultu   Проект. Agiler.  u   Проект. Service Deskr   Deviceasset.device:defaultSoftwarezasset.software:defaultVMzasset.vm:default)zSub-taskZSubtaskri  ZStoryu   ИсторияZTaskrk  rl  u   Багu   Эпикrm  u   КлассическийZAgilezService DeskZServiceDeskrn  rp  rq  r   r{   default_logic_typeu   Логический тип rx   rZ   r~   r   r   r  Tr  r   r(  r)  r   uF   Ищем логический тип по коду или имени ''r   uF   Не нашли, создаем новый логический типr$   r(   )r+   r   )rx   rZ   r  r  )r   rf   r   rh   r   r    r1  rx   r  r  r   r   rb  )r   objrz   	name2codeZlogic_type_fieldrx   Zlogic_type_dictr{   Ztemplate_coder  Zlogic_type_paramsr  r   r   r   r2  X  s    



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"    Виды деятельности   БизнесZbusinessrj     ПродажиZsales   МаркетингZ	marketing   ПроизводствоZ
production   ПоддержкаZhelpdesk   БухгалтерияZfinance!   ИТ инфраструктураZservicedesk%   Хозяйственная частьZ	household   Разработка ПОZsoftdev)	rv  rw  rx  ry  rz  r{  r|  r}  r~  u    Вид деятельности r   rx   rZ   r~   r   r   r  Tr  r   r(  r)  r   uJ   Ищем вид деятельности по коду или имени 'rs  r   uJ   Не нашли, создаем новый вид деятельности)rx   rZ   )r   rf   r   rh   r    ZCmfActivityrx   r  r  r   r   r   rb  )r   r   ru  rx   Zactivity_dictr   Zactivity_paramsr  r   r   r   r3    sZ    

zCmfPluginCsv._process_activityc                 C   s  | j jd t| j}d}t }| jD ]r}| j  r@ d S | j j| d|  |d7 }ddd|gdd|gg}tj	j
|d}|s| j jd	| d
dd |  jd7  _q*| j| D ]}zd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 |	jjdd |	jjjrN|	jjdd W q tk
r }
 z*| j jd| ddd |  jd7  _W 5 d }
~
X Y qX qq*t | }| j jd|dd d S )Nu5   Привяжем подзадачи к задачамr       из r   rx   r   r~   r   uE   Не удалось найти родительскую задачу zERR-0073r$   r   r   r   r{   r   ztask.subproject	task.epicTr  r[  u4   Не удалось привязать задачу zERR-0074u<   Обработка подзадач выполнена за .3f    сек.)r   rf   r   r   subtaskstime	monotonic	is_cancelr    r$   rh   r   r\  r   r{   r~   
startswithr   r  r`  ra  rB   r  r   )r   totalrr   t1parent_ext_idr   r   Zchild_ext_idZ_filter_childr#  rg  t2r   r   r   _process_subtasks  sR    

$zCmfPluginCsv._process_subtasksc           
   	   C   s"  | j jd t| j}d}t }| jD ]}z| j  rFW  d 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
ddd |  jd7  _W q*tjj
dd|d gd}|s| j jd|d  ddd |  jd7  _W q*tjj
dd|d gd}|s`| j jd|d  ddd |  jd7  _W q*tjj
|||d}|stj|||| j dd}d|kr|d |_d|kr|d |_|jdd W q*   | j jd| ddd |  jd7  _Y q*X q*t | }	| j jd|	d d! d S )"Nu&   Создадим связи задачr   r  typer  rZ   r   r   u2   Не удалось найти тип связи "rJ   zERR-0075CmfRelationTyper   rx   r   u=   Не удалось найти входящую задачу zERR-0076r$   out_linku?   Не удалось найти исходящую задачу zERR-0077)relation_typer   r  T)r  r   r  r   r  constrain_lagconstrain_lag_pctr  u.   Не удалось создать связь zERR-0078r   u8   Обработка связей выполнена за r  r  )r   rf   r   r   	relationsr  r  r  r    r  rh   r   r\  r$   r   r  r  r  )
r   r  rr   r  relation_datar  r   r  Zrelation_optionr  r   r   r   _process_relations  s    





zCmfPluginCsv._process_relationsc                 C   s   |  || jjd tj}|r| jjd|  d|d< | j|d< d|d< |drttjjd	d
|d d g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 )Nra   u   Грузим журнал closedr   r   Tr  
cmf_authorr   r   rx   r   r_   r  )Zminutesr  )r   r   rV   r    r&   rf   r   rh   r!   r$   Z
start_dateZ
time_spentrB   rl   Z	timedeltaZend_dater  )r   rs   Ztimetracker_historyhistoryr   r   r   _process_timetrackerS  s*    






z!CmfPluginCsv._process_timetracker
      )Z	max_triesZmax_timec                 C   s  | j jd }| ||tj}| j jjdrHtjj| j jjdd}n
| |}|r|r|dspt	d||d< |dr| 
|d|d< |d jd	rtjj|d
d|d< |dr| | |d
r|d
 |d< |dr|d
s|d= dD ]R}||}|r|dr6tjjdd|d gd}ntjjf |}|r|||< qdD ]0}||}|rVt| dkrVd||< qV| j d|  dd| j jgdddgdd|d gg}| j jjdd }	| j jjdd}
|
r(|dr(|d| j jjs(| j j d|d  |d< |drHd}	dd|d g}n.|drvd}	d dd|d gdd|d gg}|	st|d|dd! |dd! d"   }| jjj|d#d$}|" | j| j tj|||	d%\}}W 5 Q R X n| j| j tj|||	d%\}}|rtjd&| jj d'| jj  d(| j j d)d*|| j dd+}|j!dd, |j"#  | j d-| d.|d d/|d d0|d d1	 n8| j d2| d.|d d/|d d0|d d1	 | $|| | j jjd3r
tj%j| j jjd3d}n| &||}|r2|j'(  |j')| |j*rF|j!dd, |j+jj*r`|j+j!dd, |j"#  | ||tj}|r|d4r|d5r||d< | | j tj|\}}n&|r| j j,d6d7dd8 |  j-d97  _-| .| | j j"#  d S ):Nra   Ztarget_project_id)rU   rZ   u:   Не указано наименование задачи!r_   r{   r$   r  epicr   r   r   r   )r  Z	cmf_ownerr}   r   Zwaiting_forrx   r   r   r   )r   )r   Fu_   Пытаемся создать или обновить задачу по параметрам cmf_import.pluginr   r  Tmerge_identic_namesext_id_per_importr0   r~   r   r   .lockx   timeout
filter_objdont_updateuB   Задача импортирована из файла: <a href="z" target="_blank">z</a> ()   )r   Z	log_levelr_   r   r  r  u'   Создали новую задачу  ext_id= code= name='rs  u   Нашли задачу Ztarget_list_idr|   r   u   Невозможно импортировать задачу без проекта, создайте проект и укажите ID в файлеzERR-0079r   r   )/r   rV   r   r    r$   rB   rh   r(   r   r   r2  r~   r  r   r+  r!   rM   r   r   pluginrU   hashlibsha256encode	hexdigestredis_dbredislockr   r'   import_filer]   rZ   r  r  r  rh  r)   r   Zlistsr7  ro   r  r`  r   r\  r  )r   rs   ra   r#  r   rX  ru   r  r   r  r  lock_keyr  rc  Ztask_is_newZcommentr   Zcomment_objZcomment_is_newr   r   r   _process_taskm  s    








*(

"
..



zCmfPluginCsv._process_taskc                 C   s  | j jd }zR| ||tj}|s*W d S |ds<td| ||tj}|sZ|d}| |}| ||tj	}|s|d}| 
||}||d< |r|jn||d< |dr| |d|d< dd	i|d
< |dr| | |dr| ||d< | d|d|d< | d|d|d< | d|d|d< | d|d|d< | |d|d< | |d|d< |d}|r|d= | j d|  dd| j jgdddgdd|d gg}	| j jjdd }
|drd}
dd|d g}	nn|drd}
dd|d g}	nN|dr:d}
dd|d g}	n.|drhd}
ddd|d gdd|d gg}	|
s>tt|dt|dd t|dd t|d d t|d!d t|d"d t|dd t|dd d#   }| jjj|d$d%}|" | j| j tj||	|
d&\}}W 5 Q R X n| j| j tj||	|
d&\}}|r| j d'| d(|d d)|d d*|d d+	 n8| j d,| d(|d d)|d d*|d d+	 |j}| ||tj}|s|d-}| ||}|r |j !  |j "| | #|}|r@|j$!  ||_$|j%rT|j&dd. |j'(  W nJ tk
r } z*|  j)d/7  _)| j j*d0| d1dd2 W 5 d }~X Y nX | j j'(  d S )3Nra   rZ   u2   Не указано название актива.r_   r   r{   r+   rx   zasset.system:defaultr  r   r   Zownership_typeZdevice_typeZenabled_statusZoperational_statusr   r   r   u[   Попытка создать или обновить актив по параметрам r  r   r  Tr  Fr~   Zserial_numberZimeir   r   Zinv_noZphone_numberZmarkcoder  r  r  r  u#   Создан новый актив r  r  r  rs  u   Найден актив asset_typesr  r   u*   Ошибка импорта актива. zERR-0084r   )+r   rV   r   r    r+   rh   r   r   r   r   r   r_   r2  r+  r3  r   r   r   r   r  rB   r  r  rM   r  r  r  r  r  r   r   r   r  r7  ro   r   r   r  r  r  r  r\  r   )r   rs   ra   Zassetr   r   r   r   Zsupport_group_tmpr   r  r  r  Z	asset_objZasset_is_newr   r   r   excr   r   r   _process_asset  s
   










..



zCmfPluginCsv._process_assetc                 C   s   d}t dd tj| _| j r$q| \}}|d krH|||f qz2| jj	d| d|  | 
| | | W q tk
r } z<|d7 }| jjd| d| d	| d
dd | jj  W 5 d }~X Y qX qW 5 Q R X || d S )Nr   F)Zinit_views_and_dsu   Импорт строки r  r   u<   Не удалось импортировать строку z: z. zERR-0041r$   r   )r   ZAPPZREDIS_DBr  r   r  rh   putrf   r   r  r  r   r   r  Zrollback)r   	row_queuerow_queue_errors
total_rowserrorsZrow_numZrow_datar  r   r   r   _process_row_worker  s,    

*z CmfPluginCsv._process_row_workerc              
   C   s  ddl m} d}t  t  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}t }	g }
t| jD ]N}tj| jd|d  ||	|dd}|
| |  | jjd|  qt| | j
D ]f\}}| j r qj|jd r6|dkr6q||k rDq||krT qj||d |f q|d |
D ]}|  qx|	 s||	 7 }qW 5 Q R X W 5 Q R X |S )Nr   r
   r   )rU   r   r[   r\   rG   rA   rF   rT   r]   r^   c                 S   s   g | ]}d qS r   r   rC   r>   r   r   r   rE     s     z2CmfPluginCsv.process_rows_fork.<locals>.<listcomp>i  )maxsizez_process_row_worker r   )r  r  r  )targetrZ   kwargsu.   Параллельный обработчик r`   )NN)cmf.appr   r   Zdisable_aclZdisable_notifyr    rg   rh   r   ri   r  r   r4   queueZQueuerangeZthreading_max_forks	threadingThreadr  ro   startrf   r   r5   r  rV   r  r   empty)r   Zcmf_import_idstart_index	end_indexr   r  r   r  r  r  threadsrr   threadrs   r   r   r   process_rows_fork  sV    	




$zCmfPluginCsv.process_rows_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_rows_fork("z", r   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  rU   rP   r   pidZ
log_detail)r   r  r  r  procr   r   r   _execute_rows  s      & 
zCmfPluginCsv._execute_rowsc                 C   s   | j }tdd | | jD }|| }|| }| jjd t }g }t	|D ]H}|| }|| }	|d |k r||	d8 }	n|	|7 }	| 
||	}
||
 qR|D ]"}
|
  |
jr|  j|
j7  _qt | }| jjd|dd d S )Nc                 S   s   g | ]}d qS r  r   r  r   r   r   rE   +  s     z.CmfPluginCsv._process_rows.<locals>.<listcomp>u5   Запуск обработки строк файлаr   uA   Обработка строк файла выполнена за r  r  )r   r   r4   r  r   rf   r   r  r  r  r  ro   Zcommunicate
returncoder\  )r   r   r  Z
chunk_sizeZ	remainderr  Z	processesrr   r  r  r  r  r   r   r   _process_rows(  s*    
zCmfPluginCsv._process_rowsc                 C   s  |  D ]\}}i }|| d }|r|||d < | jjd|  tj| jdd}|  D ]\}	}
t||	|
 q^|  tjj	t
|jddgd}|r|n|}|jr|jr||_|jdd |j  | jjd	|j  |	d
r| |d
 ||p| qd S )Nr  u"   Обработка локации T)r   r  r   r_   rY   r  u   Создана локация children)r   r   r   rf   r   r    r,   r_  Z
_calc_namerh   rM   rZ   r  r  r_   r  r  r  _process_locations)r   	locationsZparent_location_dataZparent_location_objrZ   r-  Zcurrent_locationr   Znew_locationry   rB   Zexisting_locationr   r   r   r  G  s4    


zCmfPluginCsv._process_locationsc                 C   s6   |D ],}||d< |  | jtj|\}}|j  qd S )Nr_   )r   r   r    r   r  r  )r   asset_type_catsr   r   r   r>   r   r   r   _process_asset_type_catsh  s    z%CmfPluginCsv._process_asset_type_catsc                 C   sJ   |D ]@}||d< |  |d ||d< | | jtj|\}}|j  qd S )Nr_   r   )r   r   r   r    r   r  r  )r   r  r   r   r   r>   r   r   r   _process_asset_typesr  s    z!CmfPluginCsv._process_asset_typesc           	      C   s   |  D ]}|d }||d< |dr8| |d|d< ntjjdd|d< | | jtj|\}}|j	  |r|d D ] }| 
||}|rv|j| qv|jdd	 qd S )
Nr-  r_   rr  r   ro  r  r  Tr  )r   rh   r2  r    r1  r   r   r   r  r  r   Zasset_types_catro   r  )	r   
asset_catsr   r   asset_cat_datar   r>   r   r   r   r   r   _process_asset_cats}  s$    

z CmfPluginCsv._process_asset_catsc                 C   s   |  D ]}|d }|ds&td|ds<|d |d< dd|d g}| j| jtj||d\}}|j  |r| 	|d | | 
|d | | |d	 | qd S )
Nr-  r   uI   У схемы не указан префикс кодов активов.rx   r   )r  r  r  r  )r   rh   r   r   r   r    r   r  r  r  r  r  )r   asset_schemesr   asset_scheme_datar   r   r>   r   r   r   _process_asset_schemes  s$    



z#CmfPluginCsv._process_asset_schemesc                 C   s  | d}| d}| d}| d}| d}| d}| d}| d}	| j|d|i d	}
|
d
 |d|i d	}|d
 |d|i d	}|d
 |d|i d	}|d
 |d|i d	}|d
 |d|i d	}|d
 |d|i d	}|	rd|	d|d
 |	< d S )Ncountryareacitystreethouse_numberZfloorZflatZroom)r  rZ   r  r  )r  rZ   )rh   r  r	  )r   location_dataZcountry_nameZ	area_nameZ	city_nameZstreet_namer  Zfloor_numberZflat_numberZroom_numberr  r  r  r  r   r   r   _prepare_location_data  sz    







							z#CmfPluginCsv._prepare_location_datac                 C   sz  | j jd }| ||tj}|rvdddg}|D ].}||d}|r0| j|i }||d<  q`q0|dg }| ||tj}	|	r|	|kr|	|	 ||d< |dg }
| ||tj
}|r|	|d	< ||
kr|
	| |
|d< |d
i }| ||tj}|rndddg}|D ]2}||d}|r||i }||d<  q@q|dg }|	rf|	|krf|	|	 ||d< ||d
< d S )Nra   rx   r   r~   r   r-  r  r  r   r  rZ   )r   rV   r   r    r   rh   r  r	  r   ro   r   r   )r   rs   ra   r  r   r   r   r   r  Zasset_type_cat_datar  Zasset_type_datar  r  r   r   r   r   _prepare_asset_data  sJ    





z CmfPluginCsv._prepare_asset_datac           $      C   s  | j jd }| j jjdd}t| | jD ]d\}}| j  rH q| j jd r^|dkr^q.| ||t	j
}| ||t	j}| ||t	j}|r.dddg}|D ].}	||	d	}
|
r| j|
i }||d
<  qq|dg }| ||t	j}|r||kr|| ||d< |dg }| ||t	j}|r
|d}|rx|rx|| j jjsx| j j d|d  }||d< |s|d}|dr|d |d< |d}|r0|ds0|d= |d}|s|d }| j|g }|r|| n,|  jd7  _| j jd|d  dddd || j|< | ||t	j}|r|rd}|drh|d d }|dr<|d d }|dD ]}|||d}|}d|ksd|krd}d|krd}td|\}}|drt|d d }|| d! d" |d#< n|d$r6t|d d }|| d! |d#< nR|d%r`t|d d }|| |d#< n(|d&rt|d d }|| |d'< |d(r|d d) }d|d*< |d+r|d d) }|d,r|d d) }d|d*< |d-r|d d) }||d.< |r | j j d|d.  |d.< || jkr| j| q|d.r|d. d }|dD ]J}|||d}|r| j j d|d.  |d.< || jkr^| j| q^n,|  jd7  _| j jd|d  d/d0dd |d1|d2|d3d4}||kr
|| ||d< | || j jd t	j}|r|d5r|d5 }|d5= |dstd6|}d7|}d7|d d } |d| j|< | | jkr| j|  }|| jkrg | j|< | j| |d |d8g }!|r||!kr|!| |!|d8< |d9g }"|r$||"kr$|"| |"|d9< n<|rL|| j krL| j | |rj|| j!krj| j!| | ||t	j"}#|#r| #|# | $| q.d S ):u   
        Из строк файла собирает данные проектов, спринтов, БП, компаний и пользователей для последующего импорта
        ra   r  Fr`   r   rx   r~   rZ   r   r-  r0  r/  r0   r  r   r   u   Строка u   : Невозможно создать связь с Epic или родительской задачей. Укажите код или ИД задачи в файлеzERR-0080r$   r   zsystem.finish:startr  r   rI   )r  r   r  r   r   rQ  z[+-]rT  NrR  rW  r  rP  u   мr   r  u   ОНr  u   ООu   НОu   ННr  uy   : Невозможно создать связи задач. Укажите код или ИД задачи в файлеzERR-0081r  r   r{   )r  r   r{   r   z[,./+-]r   r   r  )%r   rV   rB   rh   r5   r4   r  r  r   r    r#   r!   r(   r,  r	  r)   ro   r$   r  rU   r  r\  r   r   r   rer  r   r  r%   r   subtasks_outliner   r  r,   r  r  )$r   ra   r  rr   rs   Zcompany_dataZperson_datar8  r   r   r   r   Zproject_sprintsZsprint_dataZproject_workflowsr#  Ztask_ext_idr   r  r  r  r  Zrelated_tasksZrelated_taskZrelationZ	task_linkZminusZlagr  rd  r   Zoutline_listZparent_outlineZproject_companiesZproject_personsr  r   r   r   _prepare_import_data+  s.   

















z!CmfPluginCsv._prepare_import_datac                 C   s  || _ |   g | _g | _i | _i | _i | _i | _g | _t	 | _
i | _i | _tjj|dddddggdgdgd| _|   | | j | | j | | j | | j | | j t  |   |   |   | j
D ]}ttjj|gd	 q| j jjd
drz| j  D ]h\}}|s"q| j j!"dt#| d|  |r`ttj$j%|t&|gd	 nttj$j't&|gd	 q| j(r| j )d| j(  | j( S )Nr[   r\   rG   rA   rF   rT   r]   r^   )argsZsend_invitesTu,   Отправляем приглашения u    пользователям: u#   Ошибок обнаружено: )*r   r   r   r  r,  r  r  r  r  r
  r6  r  r  r    ri   rh   r  r  r  r  r9  r  r  Z
cmf_commitr  r  r  Zschedule_deferred_jobr%   Z_outline_force_recalcrV   rB   r   rf   r   r   r!   Zregister_sdesk_clientr   Zregister_personsr\  r   )r   r   Zgantt_project_idr   r  r   r   r   process_import  s^    	


zCmfPluginCsv.process_import)N)N)NNr   )C__name__
__module____qualname__r   ZloggingZgetLoggerClass__annotations__r\  r   staticmethodr.   boolr@   r   r   r4   rw   r   rM   rj   rn   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r'  r+  r9  r5  r4  rh  r2  r3  r  r  r  backoffZon_exceptionZexpor   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r   r      s~   

Ek%!!%b>
 2I8.L
  6
9!
O0 ?r   )rO   Zmathcopyr   rl   r  pathlibr   typingr   r   r  r   r  r  r   r  rN   rL   r   ZdateutilZdateutil.parserr   Zcmf.includeZmodules.settings.fieldsr	   r  r   r   r   r   r   r   <module>   s*   