U
    u]f]                     @   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mZ ddl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$dHd!d"Z%edIe	j&d$d%d&Z'dJe	j&p4e	j(ed'd(d)Z)dKee	j&e	j*ed*d+d,Z+e	j&e	j,ed-d.d/Z-ee	j.e	j,pde	j&e	j/pdd0d1d2Z0e	j1e d3d4d5Z2eeed6d7d8Z3d9d: Z4ed;d< Z5eeee	j6d=d>d?Z7eeee	j6d=d@dAZ8eee9dBdCdDZ:eeee	j6e	j;e	j.dEdFdGZ<dS )Lu7  
Изначальная постановка:
    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APP)set_current_person   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tjd}|sDt	d|  d t
| tjjddd	gd
}|dk	rz||_|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||| qDq0|dt  D ]\}}t|| qr|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spt|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==filterfieldsu%   Не найден CmfPerson с login=uH   , вероятно init_demo_data запустили ДО acrm_assign.shnamez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ratecompanyr'   job)Z
contact_id   Задачиproject_namestatus w+)/cmf.includer   r   Zflushdbr   	CmfPersongetr
   Zcurrent_person_fieldsAssertionErrorr   
CmfCompanyr.   saveCmfPersonVarid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projectsr1   ZwikichatZ	chat_datatopicr)   productcostpipeline_nameoptionspipeliner.   Zcompany_dataZ	user_nameZ	user_datar'   r/   Zrolecommenttaskprojectr2   fr   r   r   create>   sx    
 
  
rh   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;   r7   r   current_personr<   r8   ri   rJ   r:   )Zobject_Zperson_varsr   r   r   rH      s    rH   c                 C   s0   d| j jkr,d| j jdd | j _|   d S )Nu   (Демо) r3   )r#   rK   replacer:   )objr   r   r   demo_fix_name   s    rm   c                 C   sF   t j|d  |dkr| }nt|d ||}t j|||d  d S )Nr*   u   Менеджерr-   )r#   r.   r'   )r   rN   r:   _create_contactrO   )rY   r/   Zjob_datarZ   r'   r   r   r   _create_worker   s
    ro   )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)   rQ   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   rP   listrr   r#   r:   r7   rI   rJ   r<   rK   __add_or_create_topic)r#   rp   rq   r)   r]   r   r   r   rE      s    rE   )r]   rp   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#   grouprr   zcreate failed)	rQ   r8   r   CmfPersonGroup
user_groupCmfChatTopicr:   load_add_comments)r]   rp   r)   r^   Zusersr   r   r   rw      s    



rw   )r^   r)   c                 C   s.   |D ]$}|  |}tjtj|| d  qd S )N)r'   messageZ
chat_topic)rR   r   ZCmfChatTopicUnreadMessager   rj   r:   )r^   r)   rd   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CmfListrv   deleteCmfDocument)kanbandocr   r   r   rV      s
    
rV   rf   c                 K   s   | dd}| dd}| dd}| d}tjj f | |||d|}|stjf | ||||d|}| d	}	tjj |	d
d}
|
r|
|_|  |rt| | 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   z:defaultTcodeZcache_inmemoryr,   folders)r7   r   rS   CmfLogicType
logic_typer:   rH   rI   rJ   r<   rK   _create_folders)r#   Zproject_dictr   r   r   r+   r   r   rf   Zlogic_type_coder   r,   r   r   r   rC      s>    
   
rC   F)rf   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 у проекта )r0   ZBacklogZSprintsZEpicsN)rD   r   ZCmfActiveEntityFilterr7   r<   _add_tasks_to_kanban_create_documentsr   r8   	CmfFolder_create_kanban)
rf   r   r,   r#   r\   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_docr4   )r5   r	   rD   r7   r=   r>   rA   endswithr   r   Zconvertr   r   r<   r:   Z
do_approveGREETINGS_DOC_ID_PATHrW   rK   rI   rJ   )r   r   r,   r	   r   titleZsettingsfilenamer[   r   r   rg   r   r   r   r     s,    
 
r   )r#   rf   r   r   c                 C   s   t j| ||dd}|jdkr6t jjddd}|r6||_|  |dd}|d	|}|sht|j	j
 |rtt| t|||d
  |S )Nr   )r#   rf   r   Z	list_typezproject.agilezlist.agile_sprint:defaultTr   r+   Fr,   r   )r   r   r   r   r7   r   r:   rI   rJ   r<   rK   rH   r   )r#   rf   r   r   r,   r   r   r+   r   r   r   r   +  s    
r   )rf   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#   Не нашлось статуса )	r8   
isinstancerB   strrD   r   rT   r7   rU   )rf   r   r   status_nameZ_tasksr2   re   r   r   r   r   A  s    r   )re   r2   r   rf   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   r3   contentr)   picturesr   )Zdays   )r   
alarm_dater#   rf   r2   rb)r   r#   z<p><img src="z"/></p>FN)!r   rB   r8   r   r7   TODAYMY_TASK_COUNTr   r   r   rj   r   CmfTaskr   r	   r>   r=   ZCmfAttachmentr#   Zupload_filerA   r:   Zurlr   r   ZapprovedZlistsrJ   r   _create_commentsrI   r<   rK   )re   r2   r   rf   r   r   r   r)   r   r   Ztask_objZcontent_imgZimg_pathZimg_path_objZimg_readZnew_attachmentr   r   r   rU   Q  sN        

rU   )re   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   )	r8   r   rB   rD   r   r:   rv   r   Z
CmfComment)re   r)   keyrK   r   r   r   r   r     s    
r   )r#   r\   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   Не нашли воронку r2   )Zwork_list_idr#   r"   u    Не нашёлся статусu3   создадим, он нам очень нужен)Z	work_listr#   N)r   r9   r7   r:   rI   rJ   r<   rK   rB   rD   rn   rG   r8   ZCmfStatusOptr   _init_auto_assign_create_dealsr2   )r#   r\   r.   contactZcontact_datara   Zstatusesrc   r   dealsoptr   r   r   rL     s    rL   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=   Сменить ответственного по сделкеr:   )captionrK   u   Сменить наr   Zmodel_m2m_choicer<   )r<   r#   rl   Zverbose_item_name)r   Z	fieldNameZ	modelNamer   rK   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
CmfTriggerr7   r<   r   rj   r#   r:   )r   Zauto_assignr   r   r   r     sJ    
   
r   c                 C   s&   |  D ]\}}t||| || qd S N)rD   _create_deal)r.   r   rc   r2   dealZ	deal_datar   r   r   r     s    r   )r#   r\   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   )r7   r   r6   r:   rI   rJ   r<   rK   r#   r\   r.   r   r'   r   r   r   rn     s
    rn   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)
r7   r   ry   rz   r6   r:   rI   rJ   r<   rK   r   r   r   r   rM     s      
rM   r#   r`   c                 C   s(   t j| |d}|  t|jj d S )Nr   )r   Z
CmfProductr:   rI   rJ   r<   rK   )r#   r`   r_   r   r   r   rF     s    rF   )r#   r\   r.   rc   r2   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   )rs   kvr   r   r   	<genexpr>  s     z_create_deal.<locals>.<genexpr>)r#   r.   totalrc   r2   ZcontactsN)r   r6   r7   r8   nextrD   r   r:   rI   rJ   r<   rK   )	r#   r\   r.   rc   r2   r   r_   r   r   r   r   r   r     s    r   )rf   )F)F)F)=__doc__r   r   r   pathlibr   r   r?   r5   r   r   r	   r
   Zcmf.appr   ZnowZutcr   r   r   rI   r>   r   r   r   rh   rH   rm   ro   rB   rE   rP   rv   rw   r{   r}   rV   rC   rS   r   r   r   r   r   r   r   rT   r6   rU   r   r   rL   r   r   r9   rn   rM   intrF   rG   r   r   r   r   r   <module>   s~   H
	


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