U
    KdO\                     @   s.  d Z ddlmZmZmZ ddlmZ ddlmZ ddlZddlm	Z	m
Z
mZ eejZdadag Zej dZd	d
 ZeedddZdd Zdd Zedd ZeeeedddZee	jeedddZee	jedddZ edd Z!dGd d!Z"edHe	j#d#d$d%Z$dIe	j#p$e	j%ed&d'd(Z&dJee	j#e	j'ed)d*d+Z(e	j#e	j)ed,d-d.Z*ee	j+e	j)prde	j#e	j,pdd/d0d1Z-e	j.ed2d3d4Z/eeed5d6d7Z0d8d9 Z1ed:d; Z2eeee	j3d<d=d>Z4eeee	j3d<d?d@Z5eee6dAdBdCZ7eeee	j3e	j8e	j+dDdEdFZ9dS )Ku7  
Изначальная постановка:
    1. Найти по email CmfPerson
    2. Создать проект P
    3. Создать внутри проекта P список L
    4. Создать внутри списка L задачу T
    5. Выставить задаче T kanban-статус S

projects:
 project:
  folder: # входящие - сразу канбан, в работе — папка с канбанами.
   kanban:
    status:
     task:
      comment1

Почему YAML, а не тупо восстановление дампа:
- нужно назначить в нужных местах правильного Person, созданного при assign
- восстановление дампа отвалится с первым же рефакторингом схемы.
    )datetime	timedeltatimezone)Path)randomN)modelsgconfig   z/custom/greetings_doc_id.txtc                    s    fdd}|S )u   
    Декоратор для логирования вызова функции и её аргументов
    :param func: функция для вызова
    c               	      sB   t dt  d  d|  d| d td7 a | |}td8 a|S )u   
        Косим под bash -x, если захочется — можно где-то тут реализовывать вложенность:
        ++ create
        +++ create_project
        ++++ create_folders
        + (z, )r
   )printTRACE_OFFSET)argskwargsresfunc ./cmf/demo_data.pywrapper-   s
    $
ztrace.<locals>.wrapperr   )r   r   r   r   r   trace'   s    r   )emailc               	   C   s  ddl m}m} |  tjjdd| gddddgd	}|sJtd
|  d |t_	tj
jdddgd}|dk	r~||_|jdd tjjdd|jgd}|stj|d  ttj d}t| }W 5 Q R X |dt }|D ]}	t|	||	  q|dt }
|
D ]}	t|	|
|	 d q
|dt  D ].\}}|d  D ]\}}t||| qHq4|dt  D ]\}}t|| qv|dt  D ]L\}}tj|d}|  |drt| |dst|jj q|dt  D ]\}}t|| q|d D ]:\}}t |||}tj!|d  d! d}|  |d  dd"stt|jj tj"|d# d! |d# d$ |||d% }|d# dd"st|jj |dt  D ]8\}}tj#j$|jjd&}|D ]}|j%d &| qq|d'g D ]F}tj'j|d(d}tj(jdd|d)d*gd}t)||d|| qq"t*  ttj+d+}|,t-t W 5 Q R X dS ),uK   
    Точка входа
    :param email: учётка админа
    r   )	CMF_CACHEcmf_pycharm_debugZlogin==companyidnameZactivityfilterfieldsu%   Не найден CmfPerson с login=uH   , вероятно init_demo_data запустили ДО acrm_assign.shzdefault.companyr"   NTZ	only_data	person_id)personz/cmf/contrib/demo_data.jsonu   ПроектыZWikisectionu   Чатыcommentsu   Продуктыu   Воронкиr    is_favoritedemo_dont_delu   Клиентыu   Пользователиu#   Штатное расписание   ИмяFu   Должностьu   Ставка)r    Zrater   r'   job)Z
contact_id   Задачиproject_namestatus w+).cmf.includer   r   Zflushdbr   	CmfPersongetAssertionErrorr   Z_current_person
CmfCompanyr   saveCmfPersonVarr   openr	   PROJECT_DIRjsonloadsreaddict_create_projectitems_create_topic_create_productCmfPipeline_add_object_to_favoritesDEMO_IDS_LISTappendvalue_create_company_create_userCmfJobCmfRoleCmfChatGroupZp2p_chattopicssend_message
CmfProject	CmfStatus_create_taskcleanupZDEMO_IDS_FILEwritedumps) r   r   r   adminmain_companyZ
person_varfddataZprojectsr0   ZwikichatZ	chat_datatopicr)   productcostpipeline_nameoptionspipeliner   Zcompany_dataZ	user_nameZ	user_datar'   r.   Zrolecommenttaskprojectr1   fr   r   r   create=   sx    
 
  
rf   c                 C   s@   t jjddtjjgdgd}|s(td|j|  |	  d S )Nr&   r   	favoritesr!   uS   У администратора ещё не созданы предпочтения)
r   r:   r6   r   current_personr   r7   rg   rH   r9   )Zobject_Zperson_varsr   r   r   rF      s    rF   c                 C   s0   d| j jkr,d| j jdd | j _|   d S )Nu   (Демо) r2   )r    rI   replacer9   )objr   r   r   demo_fix_name   s    rk   c                 C   sF   t j|d  |dkr| }nt|d ||}t j|||d  d S )Nr*   u   Менеджерr-   )r    r   r'   )r   rL   r9   _create_contactrM   )rW   r.   Zjob_datarX   r'   r   r   r   _create_worker   s
    rm   )r    
topic_name
topic_dictc                 C   s|   |d | }t jjddgdD ]X}|d dd |jD kr| |_|jdd	 |d
dsft|j	j
 t|||  qxqdS )u   
    Находит нужный чат и пишет в первую его тему список сообщений
    :param name: имя по которому ищем группу чатов
    r)   rO   zexecutors.name)r#   	executorsc                 S   s   g | ]
}|j qS r   r*   ).0executorr   r   r   
<listcomp>   s     z!_create_topic.<locals>.<listcomp>Tr%   r,   FN)r   rN   listrp   r    r9   r6   rG   rH   r   rI   __add_or_create_topic)r    rn   ro   r)   r[   r   r   r   rC      s    rC   )r[   rn   r)   c                 C   sp   |dkr | j d }|sbtdnBtj }|s6tdtj|| |gd }| j   |sbtdt|| |S )Nu   Чат группыr   zsomehow not foundu;   Не нашлось группы пользователей)r    grouprp   zcreate failed)	rO   r7   r   CmfPersonGroup
user_groupCmfChatTopicr9   load_add_comments)r[   rn   r)   r\   Zusersr   r   r   ru      s    



ru   )r\   r)   c                 C   s.   |D ]$}|  |}tjtj|| d  qd S )N)r'   messageZ
chat_topic)rP   r   ZCmfChatTopicUnreadMessager   rh   r9   )r\   r)   rb   Z
message_idr   r   r   r{      s    
r{   c                  C   sN   t j  t jjddD ]} | jdd qt jjddD ]}|jdd q8d S )Nu   Канбан1r*   T)	recursiveu   Документ1)r   Z	CmfNotifyZclose_open_notifiesCmfListrt   deleteCmfDocument)kanbandocr   r   r   rT      s
    
rT   rd   c           
      K   s   | dd}| dd}| dd}| d}tjj f | |||d|}|srtjf | ||||d|}|  |r~t| | d	d}	|	st|jj t	||d
 |	 |S )u   
    :param name: название проекта
    :param folders: список папок с задачами и канбанами внутри
    
is_defaultFr+   logic_prefixzproject.basetask_code_prefix)r    project_typer   r   )r    r   r   r   r   r,   folders)
r6   r   rQ   r9   rF   rG   rH   r   rI   _create_folders)
r    Zproject_dictr   r   r   r+   r   r   rd   r,   r   r   r   rA      s6    
   rA   F)rd   c           
      C   s   |  D ]\}}|dkrJtjjdddgdd| jggd}t| ||d  q|dkrd| }t||| q|d	krtjjd
d| jgddd	ggd}|std|  t||| q|dkrtj	jd
d| jgdd|ggd}|  D ]\}}	t
|| ||	| qqdS )u   
    :param project: ID проекта
    :param folders: список папок с задачами и канбанами внутри
    u   СогласоватьZsys_typer   Znot_approvedZfilter_parent_idr$   tasksZdocsu   Документыtree_parent_idr    uB   Не нашлась папка sys_type == docs у проекта )r/   ZBacklogZSprintsZEpicsN)rB   r   ZCmfActiveEntityFilterr6   r   _add_tasks_to_kanban_create_documentsr   r7   	CmfFolder_create_kanban)
rd   r   r,   r    rZ   r   parentfolderZkanban_namekanban_settingsr   r   r   r      s&     r   )r   textc                 C   s"  ddl m} d }| D ]\}}|d }|d|}t|j d| }| }|dsh|dr|d krddlm	}	 |	 }|
|}tjjd	d
| jgdd
|ggd}
|
stj||| d}
|
  |
  |drttd}||
jj W 5 Q R X |st|
jj W 5 Q R X qd S )Nr   )r	   filer,   /mdmarkdown)Markdownr   r   r    r$   )r    Z
text_drafttree_parentZgreetings_docr3   )r4   r	   rB   r6   r;   r<   r?   endswithr   r   Zconvertr   r   r   r9   Z
do_approveGREETINGS_DOC_ID_PATHrU   rI   rG   rH   )r   r   r,   r	   r   titleZsettingsfilenamerY   r   r   re   r   r   r   r     s,    
 
r   )r    rd   r   r   c                 C   s`   t j| ||dd }|dd}|d|}|s@t|jj |rLt| t	|||d  |S )Nr   )r    rd   r   Z	list_typer+   Fr,   r   )
r   r~   r9   r6   rG   rH   r   rI   rF   r   )r    rd   r   r   r,   r   r+   r   r   r   r   $  s    r   )rd   r   r   c                 C   s~   |dk	st dt|ts*t dt| | D ]F\}}tjjdd|gd}|s^t d| |D ]}t|||| d qbq2dS )u   
    :param project: проект к которому привязана задача
    :param kanban: список задач (CmfList), в который надо добавить
    :param tasks: список задач (в dict/list)
    Nu;   Почему-то нет объекта для спискаuR   Неожиданные задачи в виде списка без статусаr    r   r$   u#   Не нашлось статуса )	r7   
isinstancer@   strrB   r   rR   r6   rS   )rd   r   r   status_nameZ_tasksr1   rc   r   r   r   r   2  s    r   )rc   r1   r   rd   responsiblec              
   C   sz  t | tstdt|  | dd}| dd}| dg }| dg }t}	tdk rptd7 a|	tt d }	n|	td	d }	|st	j
}tj||	|||d
}
d}|D ]`}ttj| }t|d>}tj|
|jd}||  |  |d|j d }W 5 Q R X q|| |
_t |tj|
_|
jr4|
j| n||
_|
  d|
_|
  |r`t|
| |
  t|
jj  dS )u   
    :param task: заголовок задачи
    :param status: статус задачи в CRM
    :param kanban: объект списка в который это надо добавить (или None для входящих)
    :param project: объект проекта
    u@   Передан task не являющийся словарем: r   r2   contentr)   picturesr
   )Zdays   )r   
alarm_dater    rd   r1   rb)r   r    z<p><img src="z"/></p>FN)!r   r@   r7   r   r6   TODAYMY_TASK_COUNTr   r   r   rh   r   CmfTaskr   r	   r<   r;   ZCmfAttachmentr    Zupload_filer?   r9   Zurlr   r~   ZapprovedZlistsrH   r   _create_commentsrG   r   rI   )rc   r1   r   rd   r   r   r   r)   r   r   Ztask_objZcontent_imgZimg_pathZimg_path_objZimg_readZnew_attachmentr   r   r   rS   B  sN        

rS   )rc   r)   c                 C   s   | d k	st dt|trR| D ],\}}|dks@t d| || _|   q"nt|tsjt d| |D ]}|dkrntj|| d  qnd S )Nu:   Передана несуществующая задачаZdescu,   Не поддерживаемое поле: uL   Комментарии не являются списком, странно )r   r   )	r7   r   r@   rB   r   r9   rt   r   Z
CmfComment)rc   r)   keyrI   r   r   r   r   r   |  s    
r   )r    rZ   c                 C   s   t j| |ddd }t|jj |dt 	 D ]\}}t
||| q:|dt 	 D ]\}}t jj|d}|std| |	 D ]\\}}	t jj|j|dgd	}
|
std
|d t j||d}
|
  t|
 t||	||
j qqbdS )u   
    :param name: Название компании
    :param data: Сделки, Контакты и прочее пока не знаю как организованное
    u   Типr   )r    typeu   Контактыu   Сделкиr*   u   Не нашли воронку r1   )Zwork_list_idr    r#   u    Не нашёлся статусu3   создадим, он нам очень нужен)Z	work_listr    N)r   r8   r6   r9   rG   rH   r   rI   r@   rB   rl   rE   r7   ZCmfStatusOptr   _init_auto_assign_create_dealsr1   )r    rZ   r   contactZcontact_datar_   Zstatusesra   r   dealsoptr   r   r   rJ     s    rJ   c                 C   s   t d tdtjjdd| jgd}|r8t d| d S tj| jddd	d
dddddtjjtjjdtjjitjjdgdgdd| jiig dd}t d| |	  t d| d S )NuM   Для первичного контакта создаём триггер...u_   Требуется доработка готу Антон DEL cache_status_opt_id use status.idZcache_status_opt_idr   r$   u*   Триггер вроде уже есть:CmfDealZdistribution_personu=   Сменить ответственного по сделкеr9   )captionrI   u   Сменить наr   Zmodel_m2m_choicer   )r   r    rj   Zverbose_item_name)r   Z	fieldNameZ	modelNamer   rI   Zchanged_fieldscache_status_optu   При попадании на данный этап воронки автоматически будет меняться отвественный у сделки.)r   Z	cmf_modelZ	func_nameZjson_actionZ	json_dataZjson_entry_pointZjson_filterr   u   Объект в памятиu   Объект после .save())
r   	Exceptionr   Z
CmfTriggerr6   r   r   rh   r    r9   )r   Zauto_assignr   r   r   r     sJ    
   
r   c                 C   s&   |  D ]\}}t||| || qd S N)rB   _create_deal)r   r   ra   r1   dealZ	deal_datar   r   r   r     s    r   )r    rZ   r   c                 C   s8   || | dd}tjf |}|  t|jj |S )u  
    Наверное contact_data можно сразу кидать как **kwargs + company=cmp, name=name, но лень
    :param name: имя, либо имя-фамилия (по пробелу раздробится и пропишется в нужные поля)
    :param data: набор данных, пока dict из Почта: email@example.com
    :param company: компания, к которой принадлежит человек
    
   Почта)r   r    r   )r6   r   r5   r9   rG   rH   r   rI   r    rZ   r   r   r'   r   r   r   rl     s
    rl   c                 C   sN   || | dtj gd}tjf |}|  | ddsJt|jj	 |S )Nr   )r   r    r   Zrg_member_ofr,   F)
r6   r   rw   rx   r5   r9   rG   rH   r   rI   r   r   r   r   rK     s      
rK   r    r^   c                 C   s(   t j| |d}|  t|jj d S )Nr   )r   Z
CmfProductr9   rG   rH   r   rI   )r    r^   r]   r   r   r   rD     s    rD   )r    rZ   r   ra   r1   c           	      C   s   t jj|d d}|s.td|d  d|  |d sDtd|  tdd |d  D \}}t j| |||||gd	}|  t	|j
j d
S )u  
    :param pipeline: воронка продаж, в которой окажется сделка
    :param name: название сделки
    :param data: {
        Контакт: Василий Рыбин,
        Продукт: {
            Пельмени с говядиной: 400
        }
    }
    :param company: компания с которой проводится сделка
    u   Контактr*   u#   Не нашёлся контакт u    для сделки u   Продуктu5   Не указан продукт для сделки c                 s   s   | ]\}}||fV  qd S r   r   )rq   kvr   r   r   	<genexpr>  s     z_create_deal.<locals>.<genexpr>)r    r   totalra   r1   ZcontactsN)r   r5   r6   r7   nextrB   r   r9   rG   rH   r   rI   )	r    rZ   r   ra   r1   r   r]   r   r   r   r   r   r     s    r   )rd   )F)F)F):__doc__r   r   r   pathlibr   r   r=   r4   r   r   r	   ZnowZutcr   r   r   rG   r<   r   r   r   rf   rF   rk   rm   r@   rC   rN   rt   ru   ry   r{   rT   rA   rQ   r   r   r   r   r   r~   r   rR   r5   rS   r   r   rJ   r   r   r8   rl   rK   intrD   rE   r   r   r   r   r   <module>   s|   H
	


    

:,
    