U
    
@hcv                     @   s   d dl Z d dlmZmZ d dlmZ d dlmZm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m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 d dlmZ G dd dejZdS )    N)copydeepcopy)Decimal)datetimetimezone)Logger)Path)DictIterator)cached_property)commit_all_ds)*)fields
cmf_import)
log_configc                       sR  e Zd Zejjd ZdZeedddZ	dd Z
 fdd	Zd
d Zdd Zdd ZedddZed9ddZeeeef dddZdd Zedd Zeejdd Zd:eddd Zd!d" Zedd#d$Zee dd%d&Z d'd( Z!d)d* Z"d+d, Z#eejddd-d.Z$d/d0 Z%d1d2 Z& fd3d4Z' fd5d6Z(d7d8 Z)  Z*S );	CmfImport)CSV_SETTING_NAMEcsv_import_settings_fieldsloggerZCSV)returnc                 C   s   t j|  ddS )uE    Журнал логирования процесса импорта i)ZmaxBytes)r   Z
get_loggerget_files_dirself r   ./common/models/cmf_import.pyr      s    zCmfImport.loggerc                 O   s8   |    tj }tjtj | s4| j	d |S )NZinit)
r   r   ZLOG_NAMEospathexistsconfig
UPLOAD_DIRr   info)r   argskwargs	file_pathr   r   r   get_log_filename   s    zCmfImport.get_log_filenamec                    s$   | j s| jjdd| _ t   d S )Nopenstatus_type)statusworkflowget_default_statussuper_calc_statusr   	__class__r   r   r-   %   s    zCmfImport._calc_statusc                 C   s  | j d rd S | jr(| j | j d< d S | jdkr6d S | j d dtj tjjd | j d dtj	 tj	jd | j d dtj
 tj
jd | j d dtj tjjd | j d dtj tjjd | j d d	tj tjjd d S )
NZmodels_fieldsexcelu   Поля контактов)captionr   iconu   Поля задачu   Поля заметокu   Поля проектовu"   Поля списков задачu   Поля групп)json_settingspluginZcalc_models_settingstypeappendmodels	CmfPersonZimport_shop_fieldsr2   CmfTaskZ
CmfComment
CmfProjectCmfListZCmfPersonGroupr   r   r   r   _calc_models_settings*   s>    

zCmfImport._calc_models_settingsc                 K   sh   |  ddddg | jd r d S | jr<| jj| d| jd< n| jdkrT|  | jd< | j| _|   d S )Nr3   attachmentsr5   r4   import_settingsr   r0   )load_fieldsr3   r4   calc_import_settingsr5   calc_import_excel_settingssaver   r#   r   r   r   r@   E   s    

zCmfImport.calc_import_settingsc                 K   sH   |  ddddg | jd r d S | jj| d| jd< | j| _|   d S )Nr3   r=   r5   r4   r>   r   )r?   r3   r4   tmplt_import_settingsrB   rC   r   r   r   rD   S   s    
zCmfImport.tmplt_import_settingsc                 C   s   | j d j}d}d}z|  }t|D ]\}}q&W n tk
rt } z$| d| d| d|  d}W 5 d }~X Y n tk
r } z$| d| d| d|  d}W 5 d }~X Y nF ttfk
r } z$| d| d| d|  d}W 5 d }~X Y nX |S )Nr   FuJ   Не корректный формат загружаемого файла:T*   Приложен пустой файл CSVu5   Не удаётся прочитать строчку)	r=   full_path_file	_get_file	enumerateUnicodeDecodeError
_log_errorStopIterationIOError
ValueError)r   r$   
have_errorZnum	file_read_er   r   r   _check_file[   s"    zCmfImport._check_file c                 C   s4   d|  d d} td|  d|  t|  d S )Nu1   Ошибка при импорте данных. .ue   . Проверьте загружаемый файл и повторите попытку снова.zCmfImportError: : )striploggingerrorZ	cmf_alert)msgrR   r   r   r   rK   n   s    zCmfImport._log_errorc            
      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}i }|  D ]N\}}|dd}|dd}tt|}	||| d| |	jd|	jd||< q|S )ug    Структура сопоставления полей из файла CSV по умолчанию. r9   r:   r;   name)
field_name
model_namecodetextr)   Z
alarm_dateZdeadlinepriorityzresponsible.namezresponsible.emailzcmf_author.namezcmf_author.emailzexecutors.namezexecutors.emailzparent_task.codezchild_tasks.codeZtask_code_prefixlogic_prefixactivity)u   Тема задачиu   Код задачиu   Описание задачиu   Статус задачиu   Будильник задачиu"   Крайни срок задачиu   Важностьu   ФИО исполнителяu   Email исполнителяu   ФИО автораu   Email автораu!   ФИО соисполнителяu    Email соисполнителяu$   Код основной задачиu$   Код дочерней задачиu   Название проектаu   Код проектаu   Префикс задачu   Тип проектаu   Вид деятельностиu   Список задачr]   rT   r\   rU   T)r1   r\   field_qualnamer2   requiredverbose_name)itemsgetgetattrr7   r2   re   )
Zname_cmf_taskZname_cmf_projectZname_cmf_epicdefault_mappingZdefault_local_attrs_mappingtitleZvalue_modelr]   Z	name_attrmodelr   r   r   _default_mapping_csvt   sL    
zCmfImport._default_mapping_csvc              	   C   s  | j s
d S tjjdgdd| jgdgd}| jg d}|  }|rDg S |  }|  }t	|D ]&\}}|dkr| j
d s qn|d	kr qt	|D ]\}}	d
}
|dkrH|r(|j
d r(t|j
d D ]Z}d|krd|kr q(|d | jkrq|d D ]&}|d |	kr|d | d}
 qqq|
s|d |	d d d d q|d | }||d }|	|d< |r||d< |d |d< qq\|d s| d g S |gS )Nz-cmf_modified_atidz!=r3   )Zorder_byfilterr   r[   r   r   	first_row   Fr>   r[   r   rj   T)rj   file_valmodel_fieldr2   rr   rs   r2   rF   )r=   r7   r   rg   rm   r   rS   rH   rl   rI   r3   r   r6   rK   )r   Zprev_settingssettingsrO   rP   ri   irowjvalfoundZprev_setZ
prev_fieldZrow_settingsrs   r   r   r   rA      sZ    
 


z$CmfImport.calc_import_excel_settingsc                 C   s:   |  dg | jd D ]}|d | jkr|d   S qg S )Nr3   r>   r[   r   )r?   r3   r   )r   rt   r   r   r   r      s
    z$CmfImport.csv_import_settings_fieldsc              
   O   s&  dt jd< t  t  tjj| dddgd}|j	d |j
jdd	|_|  t  | }|r|j	d
 |j
jdd	|_|  n0|jjdkr|j	d |j
jdd|_|  |jjd jtjd}W 5 Q R X W 5 Q R X tjj|tjjj|jdttj dd| ddd dS )uJ   
        Запускаем в фоне импорт данных
        1importr*   r)   Zprogressrm   r   u%   ***Запускаем импорт***Zin_progressr'   u2   ***Импорт успешно завершен***closedu7   ***Импорт завершен с ошибками***import-errorZstatus_coder   z/files/u+   Импорт данных завершен z%d.%m.%Y %H:%Mz
, <a href=u(   >Журнал логирования</a>T)objZ	person_idr[   rZ   Zis_notify_current_personN)!r   environcmfutildisable_acldisable_notifyr7   r   rg   r   r!   r*   r+   r)   rB   commit_with_eventprocess_importr(   ZhandlersZbaseFilenamereplacer   r    Z	CmfNotifyZplace_notifygZcurrent_personrm   valuer[   r   nowr   utc)Z	import_id_args_kwargsr   resZlog_pathr   r   r   start   s0    

,zCmfImport.startN)rv   c              	   C   s4  d}|dkr|j }|sg }i }t| jD ]Z\}}|d r(|| r(|d d dd |jkr^q(|d d |kr(|| ||d d < q(|s|S || d}	tt|	d	}
|D ]}|j|}t	|tj
st	|tjr,d}| D ]8}|jd
dd|| gd	d|| ggdgd}|r qq|r,t|	|| qt	|tjr<qt|	|||  || }t	|tjr~t|d}t|tjj}t	|tjrq||d|g q| jd r|j|dgd}|s0|d	}|r|j|dgdd}|r|
|	_|j|	jdgd}|r$|	j dttjd|	_|	}|  |S )u  
        Импортируем объект

        :param list row: Строка из файла
        :param models.* model: Модель для создания объекта
        :param list _filter: Для фильтрации объекта
        :param str key: Ключевое имя для сопоставления модели

        :return: Новый или найденный объект
        :rtype: Optional[models.*]
        Nrs   rc   rU   r   re   r\   r   r^   ORr[   ==z**)rn   r   ZRUunionT)r^   r   Zinclude_deletedro   rQ   z%Y%m%d-%H%M%S)re   rI   r   split
class_namestrrh   r   rg   
issubclassZCmfRelationZCmfGenericRelationZrelated_modelssetattrZ
CmfRelBaseZCmfPhonephonenumbersparseZformat_numberZPhoneNumberFormatZINTERNATIONALZ
CmfNumericr6   r3   r^   r[   r   r   r   r   rB   )r   rv   rk   _filterkeyresult_fieldsru   settingZnew_objZnew_coder\   ZfieldZrel_objZ	rel_modelrx   Zphoner^   r   r   r   _process_obj  sp    

zCmfImport._process_objc              
   C   s   |  dddddg | jrz0t  | jj| dW  5 Q R  W S Q R X W n tk
r } zl| dt  }t| t	| dt
|jd	  }| j| || _| jjd
d| _|   W Y dS d}~X Y nX | jdkr|  S dS )u9   
        Импортируем файл в бд
        r0   r>   rp   r4   r=   r   rV   
r~   r   FN)r?   r4   r   Zenable_import_moder   	Exception	traceback
format_excr   r   	format_tb__traceback__r   	exception	error_msgr*   r+   r)   rB   r5   _process_import_excel)r   errerr_msg
error_textr   r   r   r   O  s     
&
zCmfImport.process_importc           4      C   sf  ddl m} | jr| jd s dS d}zi }i }i }i }i }i }i }	|  }
t|
D ](\}}|dkrr| jd rrqTi }i }d}d}t| jD ],\}}|d r|| sq|d d d	d }||i }|d d
 d	}|d }|| }|dkr|}qn|dkr|}qt	|dkrP|dkr2|||d < q||i }|| ||d < nZ|dkrt|dkrt|
|| }n6|dkr||| }n|dkrd||| i}|||< |||< q|di }|dd}||d}|s|| tj|\}}|||d< || tj|\}}|di }|drD|d |d< |di }|r|	|}|s|dkrtjjddtjjddd}ntjjddtjjddd}||	|< ||d < ||d< ||d!< ||d"< d#d$d%|jgdd%|d gg}|| tj||\} }| j| |   | ||d < |rH||g }!|!|  |!||< |rt||d g }"|"| |"||d < |d&i d'd}#|#r|# d(|jj }$||$i }%||%d!< |#|%d'< |%d)g }&|&|  |&|%d)< |%||$< ||d}'|'sftjjd#d*d%|jgd'd%d+ggd,}(d#d*d%|(jgd'd%d-gg})d-||(d.d/}*|j| tj|*|)d0\}'}|'||d< || jtj|'| d1 qT|  D ]\}$}+tjjd#d*d%|+d! jgd'd%d2ggd,}(d#d*d%|(jgd'd%|+d' gdd3d4gg})tjj|)d,},|,stj|+d! |(|+d' tj!jd5dd6},|,  |+d) D ]} |,| _"| jd7d8 q"q|  D ]>\}}-||}.|.rH|-D ]}/|/j"#  |.|/_"|/  qdqH|  D ]N\}}0||}.|.r|0D ].}1||1}/|/r|/j"#  |.|/_"|/  qqW n~ t$k
r` }2 z^t%|2 d9| d:|2 d;t&'|2j(d<  }3| j)*|3 |3| _+| j,j-d=d>| _.|   W Y dS d?}2~2X Y nX d7S )@u   
        Запуск импорта из CSV

        :return: Истина в случае успешного импорта
        r   )CmfPluginImportMixinr>   Frp   rT   rs   rc   rU   r\   parent_taskZchild_tasksrq   	executorsra   r:   r`   r)   r(   zproject.agiler^   r9   Z
cmf_authorZ	cmf_ownerzproject.basez
task.base%baser^   )Z	cmf_modelprefixrb   ztask.agile:softdev%Zsoftdevr*   projectparentZANDZ	parent_idr   r;   r[   rQ   tasksZtree_parent_idZSprints)rn   u
   ДоскаZkanban)r[   r   tree_parentZ	list_type)r   rk   
obj_fields
filter_obj)leftrightZEpics=z	task.epicztask.epic:default)r   r   r[   Z
logic_typeT)Z	only_datau   Строка rV   r   r   r~   r   N)/Z%common.models.cmf_plugin_import_mixinr   r=   r3   rH   rI   r   r   rg   lenZget_logic_prefixZget_priorityZget_status_type
setdefaultZprocess_any_table_fieldsr7   r:   r8   CmfWorkflowZcalc_workflowZCmfActivityrm   r9   r   r6   rB   r^   r   Z	CmfFolderr;   r   ZCmfListCmfTaskrf   ZCmfLogicTyper   loadr   r   r   r   r   r   r   r   r*   r+   r)   )4r   r   Z
number_rowZall_parent_taskZall_child_tasksZall_epic_tasksZ	all_tasksZ
cash_boardZcash_projectZcash_workflow_taskrP   rv   executorr   Zparent_task_codeZchild_tasks_codeidxr   r]   Z_rowZfields_namer\   r   Zproject_fieldsra   r   rQ   Zexecutor_objZtask_fieldsZvalue_statusr*   Zfilter_taskZtask_objZtmp_parent_tasksZtmp_child_tasksZ	epic_nameZepic_keyZtmp_dataZ	tmp_tasksZlist_objZparent_folderr   r   dataZepic_objr   r   Zsub_taskZ
tasks_codeZsub_task_coder   r   r   r   r   r   e  sL   








 



 




"zCmfImport._process_import_excelc              	   c   s   t | jd j}|jdkrRtt|}|d}| D ]}dd |D V  q:nn|jdkrt	
t|}|j}|jddD ]
}|V  q|n6|jdkrt|d	}t|D ]
}|V  qW 5 Q R X d S )
Nr   z.xlsc                 S   s   g | ]
}|j qS r   )r   ).0itemr   r   r   
<listcomp>,  s     z'CmfImport._get_file.<locals>.<listcomp>z.xlsxT)Zvalues_onlyz.csvr)r   r=   rG   suffixxlrdZopen_workbookr   Zsheet_by_indexZget_rowsopenpyxlZload_workbookZactiveZ	iter_rowsr&   csvreader)r   Zattachment_file_pathZworkbookZ	worksheetelfiler   r   r   rH   &  s     




zCmfImport._get_filec                 C   s>  |  |tj}|r|sdS d}| jD ] }|d r$|d d dkr$|}q$|dg tjj|jt|d |j	jdgd}|stj|t|d |j	| d	}|
  |jjd
d t|jjD ]*}|jj| jkrq|  |jj| q| j |tjtjjdd|jgdd|jggd}|ddg ||_||_|jr:|
  |S )u;   
        Импорт товара в сделку
        Nrs   rc   zCmfProduct.pricescurrencyrr   price)
product_idr   Zcurrency_idr   )productr   r   r   T)forceZdeal_idr   r   )r   r   r   Zsales_order)r   r7   Z
CmfProductr   r?   ZCmfPricerg   rm   r   r   rB   Zpricesr   r   Z
deal_itemsr   r   deleteremoveZCmfDealItemsre   dealr   
is_changed)r   rv   r   r   Zprice_settingrt   r   r   r   r   r   _process_product8  s@    
 zCmfImport._process_productc           	      C   s  |s|r|j sd S d }| jD ] }|d r|d d dkr|}q|sFd S g }tjj|d d}|sxtj|d d}|  |dd|jg |r|dd|jg n|dd|j jg | |tj	|}|
d	d
g |j s|r||_ n|j |_ |js||_|jr
|  |S )Nrs   rc   zCmfDeal.pipelinerr   )r[   Zpipeline_idr   Z
company_idcompanypipeline)r   r   r7   ZCmfPipelinerg   rB   r6   rm   r   CmfDealr?   r   r   )	r   rv   Zcontactr   Zpipeline_settingrt   r   r   r   r   r   r   _process_dealY  s8    
zCmfImport._process_dealc                 C   s<   t jj| jdgd}|jjdkr8d|_|jr4|  dS dS )Nr)   r|   )import-cancelingimport-canceledr~   import-stoppingr   TF)r7   r   rg   rm   r)   r^   r   rB   )r   r   r   r   r   	is_cancel|  s    zCmfImport.is_cancelc                  O   s  t   t  ~ tjj|d ddgd}|jjdkr|jjdkrf|jj	dd|_|
  t  td	D ]t}td
 tjj|jddgd}|jjdkr q|dkrnd|_|jj	dd|_|
   W 5 Q R  W 5 Q R  dS qnn|jj	dd|_|
  t  zz4|j  |jD ]}|  q|jj	dd|_W nF tk
r } z&t| t||_|jj	dd|_W 5 d}~X Y nX W 5 |
  X W 5 Q R X W 5 Q R X dS )u/   
        Отменяем импорт
        rm   r)   r*   r|   )import-startedr   r   r   r   <   rq   r   ;   u5   Не удалось остановить импортr~   Nr   )r   r   r   r7   r   rg   r)   r^   r*   r+   rB   r   rangeZgeventsleeprm   r   Zimport_objectsr   r   r   r   r   )r"   r#   r   ru   rv   rR   r   r   r   cancel  s<    



&zCmfImport.cancelc                 O   s<   |  ddddg | jr&| jj| dS | jdkr8|  S dS )uk   
        Предварительный просмотр получившихся объектов
        r3   r=   r5   r4   r   r0   N)r?   r4   previewr5   preview_excel)r   r"   r#   r   r   r   r     s
    
zCmfImport.previewc                 C   s  g }ddg g d}d}|   }| jd r0t| t|D ]\}}|dkrL qg }|d | t| jD ]l\}}	|	d szqh|	d d	 d
d }
|s|
dkrd}|
dkrh|dkr|d |	d d  |||  qhq8|d r|| |sd|d< d|d< |S )Nu   СделкиZ	handshake)rj   r2   titlesrowsFrp   rq   r   rs   rc   rU   r   r   T)r   r9   r   r1   u   Задачиrj   zcalendar-todayr2   )rH   r3   nextrI   r6   r   r   )r   r   ZdealsZis_dealrP   ru   rv   Zdata_rowrw   rt   r]   r   r   r   r     s6    

zCmfImport.preview_excelc                    s   t   dddddg S )Nr3   r=   r5   r)   r4   )r,   save_preload_fieldsr   r.   r   r   r     s    zCmfImport.save_preload_fieldsc                    s   |    t jf |S )N)r<   r,   rB   rC   r.   r   r   rB     s    zCmfImport.savec                 C   s@   | j r
d S | jr,| jjdkr,tjjdd| _ tjjdd| _ d S )NZCmfPluginJirazimport.system.jira:defaultr   zimport.system:default)r*   r4   r   r7   r   rg   r   r   r   r   _calc_workflow  s
    zCmfImport._calc_workflow)rT   )NN)+__name__
__module____qualname__r   r   Zui_meta_skipr   r   r   r   r%   r-   r<   r@   rD   boolrS   staticmethodrK   r	   r   rl   rA   r   Z
celery_appZtaskr   listr   r   r   r
   rH   r   r   r   r   r   r   r   rB   r   __classcell__r   r   r.   r   r      sH   ,6
 N B!#	'
r   )r   r   r   Zdecimalr   r   r   rX   r   r   pathlibr   typingr	   r
   r   r   r   r   Zcmf.data_providers.baser   Zcmf.includeZcmfr   Zcommon.fieldsr   Zcmf.modules.logsr   r   r   r   r   r   <module>   s"   