B
    aEf]                 @   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kwargsZ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 dQ R X |dt }x|D ]}	t|	||	  qW |dt }
x|
D ]}	t|	|
|	 d qW xH|dt  D ]2\}}x&|d  D ]\}}t||| qPW q:W x*|dt  D ]\}}t|| qW xb|dt  D ]L\}}tj|d}|  |drt| |dst|jj qW x*|dt  D ]\}}t || qW xZ|d D ]F\}}t!|||}tj"|d d d}|  |d ddst|jj tj#|d  d |d  d! |||d" }|d  ddst|jj xR|dt  D ]<\}}tj$j%|jjd#}x|D ]}|j&d '| qW qW xV|d$g D ]F}tj(j|d%d}tj)jdd|d&d'gd
}t*||d|| q:W q>W t+  ttj,d(}|-t.t W dQ R X dS ))uK   
    Точка входа
    :param email: учётка админа
    r   )	CMF_CACHEcmf_pycharm_debugZloginz==)filterfieldsu%   Не найден CmfPerson с login=uH   , вероятно init_demo_data запустили ДО acrm_assign.shnamezdefault.company)r   NT)	only_data	person_id)personz/cmf/contrib/demo_data.jsonu   ПроектыZWikisectionu   Чатыcommentsu   Продуктыu   Воронки)r   is_favoritedemo_dont_delu   Клиентыu   Пользователиu#   Штатное расписаниеu   ИмяFu   Должностьu   Ставка)r   Zratecompanyr"   job)Z
contact_idu   Задачиproject_namestatus z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projectsr)   ZwikichatZ	chat_datatopicr$   productcostpipeline_nameoptionspipeliner'   Zcompany_dataZ	user_nameZ	user_datar"   r(   Zrolecommenttaskprojectr*   fr   r   r   create>   sp    


r_   c             C   s@   t jjddtjjgdgd}|s(td|j|  |	  d S )Nr!   z==	favorites)r   r   uS   У администратора ещё не созданы предпочтения)
r   r2   r.   r   current_personr3   r/   r`   rA   r1   )Zobject_Zperson_varsr   r   r   r?      s    r?   c             C   s0   d| j jkr,d| j jdd | j _|   d S )Nu   (Демо) r+   )r   rB   replacer1   )objr   r   r   demo_fix_name   s    rd   c             C   sF   t j|d  |dkr| }nt|d ||}t j|||d  d S )N)r   u   Менеджерu   Имя)r   r'   r"   )r   rE   r1   _create_contactrF   )rP   r(   Zjob_datarQ   r"   r   r   r   _create_worker   s
    rf   )r   
topic_name
topic_dictc             C   s~   |d | }xlt jjddgdD ]V}|d dd |jD kr | |_|jdd	 |d
dsht|j	j
 t||| P q W dS )u   
    Находит нужный чат и пишет в первую его тему список сообщений
    :param name: имя по которому ищем группу чатов
    r$   rH   zexecutors.name)r   	executorsc             S   s   g | ]
}|j qS r   )r   ).0executorr   r   r   
<listcomp>   s    z!_create_topic.<locals>.<listcomp>T)r    r&   FN)r   rG   listri   r   r1   r.   r@   rA   r3   rB   __add_or_create_topic)r   rg   rh   r$   rT   r   r   r   r<      s    r<   )rT   rg   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   groupri   zcreate failed)	rH   r/   r   CmfPersonGroup
user_groupCmfChatTopicr1   load_add_comments)rT   rg   r$   rU   Zusersr   r   r   rn      s    



rn   )rU   r$   c             C   s2   x,|D ]$}|  |}tjtj|| d  qW d S )N)r"   messageZ
chat_topic)rI   r   ZCmfChatTopicUnreadMessager   ra   r1   )rU   r$   r[   Z
message_idr   r   r   rt      s    

rt   c              C   sV   t j  x"t jjddD ]} | jdd qW x"t jjddD ]}|jdd q>W d S )Nu   Канбан1)r   T)	recursiveu   Документ1)r   Z	CmfNotifyZclose_open_notifiesCmfListrm   deleteCmfDocument)kanbandocr   r   r   rM      s
    
rM   r]   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)codecache_inmemoryr&   folders)r.   r   rJ   CmfLogicType
logic_typer1   r?   r@   rA   r3   rB   _create_folders)r   Zproject_dictr   r   r|   r%   r}   r~   r]   Zlogic_type_coder   r&   r   r   r   r:      s,    

r:   F)r]   c       
      C   s  x|  D ]\}}|dkrLtjjdddgdd| jggd}t| ||d  q
|dkrf| }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}x$|  D ]\}}	t
|| ||	| qW q
W dS )u   
    :param project: ID проекта
    :param folders: список папок с задачами и канбанами внутри
    u   СогласоватьZsys_typez==Znot_approvedZfilter_parent_id)r   tasksZdocsu   Документыtree_parent_idr   uB   Не нашлась папка sys_type == docs у проекта )u   ЗадачиZBacklogZSprintsZEpicsN)r;   r   ZCmfActiveEntityFilterr.   r3   _add_tasks_to_kanban_create_documentsry   r/   	CmfFolder_create_kanban)
r]   r   r&   r   rS   rz   parentfolderZkanban_namekanban_settingsr   r   r   r      s"     r   )r   textc             C   s*  ddl m} d }x| D ]\}}|d }|d|}t|j d| }| }|dsl|dr|d krddlm	}	 |	 }|
|}tjjd	d
| jgdd
|ggd}
|
stj||| d}
|
  |
  |drttd}||
jj W d Q R X |st|
jj W d Q R X qW d S )Nr   )r	   filer&   /mdmarkdown)Markdownr   z==r   )r   )r   Z
text_drafttree_parentZgreetings_doczw+)r,   r	   r;   r.   r4   r5   r8   endswithr   r   Zconvertr   ry   r3   r1   Z
do_approveGREETINGS_DOC_ID_PATHrN   rB   r@   rA   )r   r   r&   r	   r   titleZsettingsfilenamerR   r   r{   r^   r   r   r   r     s,    
 r   )r   r]   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 )Nrz   )r   r]   r   Z	list_typezproject.agilezlist.agile_sprint:defaultT)r   r   r%   Fr&   r   )r   rw   r}   r   r.   r   r1   r@   rA   r3   rB   r?   r   )r   r]   r   r   r&   rz   r   r%   r   r   r   r   +  s    
r   )r]   rz   r   c             C   s   |dk	st dt|ts*t dt| xV| D ]J\}}tjjdd|gd}|s`t d| x|D ]}t|||| d qfW q4W dS )u   
    :param project: проект к которому привязана задача
    :param kanban: список задач (CmfList), в который надо добавить
    :param tasks: список задач (в dict/list)
    Nu;   Почему-то нет объекта для спискаuR   Неожиданные задачи в виде списка без статусаr   z==)r   u#   Не нашлось статуса )	r/   
isinstancer9   strr;   r   rK   r.   rL   )r]   rz   r   status_nameZ_tasksr*   r\   r   r   r   r   A  s    
r   )r\   r*   rz   r]   responsiblec          
   C   s~  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}xh|D ]`}ttj| }t|d>}tj|
|jd}||  |  |d|j d }W dQ R X qW || |
_t |tj|
_|
jr8|
j| n||
_|
  d|
_|
  |rdt|
| |
  t|
jj  dS )u   
    :param task: заголовок задачи
    :param status: статус задачи в CRM
    :param kanban: объект списка в который это надо добавить (или None для входящих)
    :param project: объект проекта
    u@   Передан task не являющийся словарем: r   r+   contentr$   picturesr   )Zdays   )r   
alarm_dater   r]   r*   rb)r   r   z<p><img src="z"/></p>NF)!r   r9   r/   r   r.   TODAYMY_TASK_COUNTr   r   r   ra   r   CmfTaskr   r	   r5   r4   ZCmfAttachmentr   Zupload_filer8   r1   Zurlr   rw   ZapprovedZlistsrA   r   _create_commentsr@   r3   rB   )r\   r*   rz   r]   r   r   r   r$   r   r   Ztask_objZcontent_imgZimg_pathZimg_path_objZimg_readZnew_attachmentr   r   r   rL   Q  sD    
 

rL   )r\   r$   c             C   s   | d k	st dt|trVxR| D ],\}}|dksBt d| || _|   q$W nt|tsnt d| x&|D ]}|dkrttj|| d  qtW d S )Nu:   Передана несуществующая задачаZdescu,   Не поддерживаемое поле: uL   Комментарии не являются списком, странно )r   r   )	r/   r   r9   r;   r   r1   rm   r   Z
CmfComment)r\   r$   keyrB   r   r   r   r   r     s    

r   )r   rS   c             C   s  t j| |ddd }t|jj x*|dt 	 D ]\}}t
||| q<W x|dt 	 D ]\}}t jj|d}|std| xh|	 D ]\\}}	t jj|j|dgd	}
|
std
|d t j||d}
|
  t|
 t||	||
j qW qhW dS )u   
    :param name: Название компании
    :param data: Сделки, Контакты и прочее пока не знаю как организованное
    u   Типr'   )r   typeu   Контактыu   Сделки)r   u   Не нашли воронку r*   )Zwork_list_idr   r   u    Не нашёлся статусu3   создадим, он нам очень нужен)Z	work_listr   N)r   r0   r.   r1   r@   rA   r3   rB   r9   r;   re   r>   r/   ZCmfStatusOptr   _init_auto_assign_create_dealsr*   )r   rS   r'   contactZcontact_datarX   ZstatusesrZ   r   dealsoptr   r   r   rC     s    rC   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_idz==)r   u*   Триггер вроде уже есть:CmfDealZdistribution_personu=   Сменить ответственного по сделкеr1   )captionrB   u   Сменить наr   Zmodel_m2m_choicer3   )r3   r   rc   Zverbose_item_name)r   Z	fieldNameZ	modelNamer   rB   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
CmfTriggerr.   r3   r   ra   r   r1   )r   Zauto_assignr   r   r   r     s6    



r   c             C   s*   x$|  D ]\}}t||| || q
W d S )N)r;   _create_deal)r'   r   rZ   r*   dealZ	deal_datar   r   r   r     s    r   )r   rS   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: компания, к которой принадлежит человек
    u
   Почта)r'   r   r   )r.   r   r-   r1   r@   rA   r3   rB   )r   rS   r'   r   r"   r   r   r   re     s
    re   c             C   sN   || | dtj gd}tjf |}|  | ddsJt|jj	 |S )Nu
   Почта)r'   r   r   Zrg_member_ofr&   F)
r.   r   rp   rq   r-   r1   r@   rA   r3   rB   )r   rS   r'   r   r"   r   r   r   rD     s    rD   )r   rW   c             C   s(   t j| |d}|  t|jj d S )N)r   rW   )r   Z
CmfProductr1   r@   rA   r3   rB   )r   rW   rV   r   r   r   r=     s    r=   )r   rS   r'   rZ   r*   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 )Nr   )rj   kvr   r   r   	<genexpr>  s    z_create_deal.<locals>.<genexpr>)r   r'   totalrZ   r*   ZcontactsN)r   r-   r.   r/   nextr;   r   r1   r@   rA   r3   rB   )	r   rS   r'   rZ   r*   r   rV   r   r   r   r   r   r     s    
r   )r]   )F)F)F)=__doc__r   r   r   Zpathlibr   r   r6   r,   r   r   r	   r
   Zcmf.appr   ZnowZutcr   r   r   r@   r5   r   r   r   r_   r?   rd   rf   r9   r<   rG   rm   rn   rr   rt   rM   r:   rJ   r   ry   r   r   r   rw   r   rK   r-   rL   r   r   rC   r   r   r0   re   rD   intr=   r>   r   r   r   r   r   <module>   s`   H


6,