#include "stdafx.h"
#include "dictionary.h"

#include "PSMDoc.h"

/*#include "aplTopLevelItem.h"
#include "aplFolderTreeItem.h"
#include "aplMessageTreeItem.h"*/
#include "aplMessageFolderTreeItem.h"
#include "aplTreeTaskItem.h"
#include "aplTreeProcessItem.h"
#include "aplBPTreeItem.h"
#include "aplChangeTreeItem.h"
#include "CaplRefusalTreeItem.h"
#include "TreeProductItem.h"
#include "aplDocTreeItem.h"
#include "TabView.h"

#include "resource.h"

bool CaplTaskTreeItem::m_ShowSuspended= false;
bool CaplTaskTreeItem::m_ShowCompleted= false;
bool CaplTaskTreeItem::m_ShowCanceled= false;

bool CaplTaskTreeItem::CheckNewTasks(CPSMDoc* doc)
{
	int i;
	bool bRes= false; 

	CaplInstance* inst;
	CaplInstance* person=doc->m_api.m_appr_mgr.GetCurrentPerson();
	if(person==0) return false;

	CaplAttrValue val[3];
	aplExtent ext, ext1;
	
	val[0].value.Set(person);
	val[0].attr= doc->m_wf_mgr.a_task_performer;
	val[1].value.Set(_T("active"));
	val[1].attr= doc->m_wf_mgr.a_task_state;
	
	//исполнитель задания не подтвердил получение задания
	doc_data.NET_FindInstancesWithAttrValues(doc->m_wf_mgr.e_task, 2, 
		&val[0], ext, false);
	
	CString buf, sDate;
	COleDateTime odt;
	doc_data.NET_GetServerDateTime(odt);
	aplDate2String(odt, sDate);
	CaplLoadData ld(&doc->m_api.m_data,DEF_SOURCE);
	if(doc->m_wf_mgr.a_task_notify_date)
	{
		for(i= 0; i<ext.GetSize(); i++)
		{
			ld.AddQuery(0, ext[i]);
		}
		if(i>0)
		{
			ld.AddQuery(_T('d'), 0, 0, doc->m_wf_mgr.a_task_notify_date, true);
			ld.LoadEx();
		}
		
		bool bSave= false;
		for(i= 0; i<ext.GetSize(); i++)
		{
			doc_data.GetAttr(ext[i], doc->m_wf_mgr.a_task_notify_date, buf);
			if(buf.IsEmpty())
			{
				doc_data.PutAttr(ext[i], doc->m_wf_mgr.a_task_notify_date, sDate);
				bSave= true;
				bRes= true;
			}
		}
		if(bSave)
		{
			doc_data.NET_SaveChanges();
		}
	}

	val[0].value.Set(person);
	val[0].attr= doc->m_wf_mgr.a_task_manager;
	inst= NULL;
	val[1].value.Set(inst);
	val[1].attr= doc->m_wf_mgr.a_task_performer;
	val[2].value.Set(_T("active"));
	val[2].attr= doc->m_wf_mgr.a_task_state;
	
	//ответственный не назначил исполнителя
	doc_data.NET_FindInstancesWithAttrValues(doc->m_wf_mgr.e_task, 3, 
		&val[0], ext1, false);
	
	ext.Append(ext1); 

//	if(0!=ext.GetSize())
//		bRes= true;

	return bRes;
}

//CaplTaskTreeItem
CaplTaskTreeItem::CaplTaskTreeItem(CTreeCtrl *tree, CPSMDoc *doc, CaplInstance* inst, long g_mode)
{
	m_type= APL_TREE_ITEM_TASK;
	m_doc= doc;
	m_tree= tree;
	m_task= inst;
	m_g_mode= g_mode;
	m_bProcShow= false;
	m_bPrevShow= false;
	m_bIsParent=false;
	if(doc!=0) 
		doc->m_items.Add(this);	
}

bool CaplTaskTreeItem::GetName(CString &name)
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	CHECK_GET_NAME(m_task);
	
	name= _T("");

	if(m_doc->m_api.m_show.m_show_task_id)
	{
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_action_id, name);
	}
	CString buf;
	if(m_doc->m_api.m_show.m_show_task_name)
	{
		if(name!=_T(""))
			name+=_T(" : ");
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_action_name, buf);
		name+=buf;
	}
	if(m_doc->m_api.m_show.m_show_task_process_id || m_doc->m_api.m_show.m_show_task_process_name)
	{
		name+=_T(" [ ");
		CaplInstance *proc;
		CString buf1;
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, proc);
		if(0!=proc)
		{
			if(m_doc->m_api.m_show.m_show_task_process_id )
				m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_action_id, buf);
			else buf=_T("");
			if(m_doc->m_api.m_show.m_show_task_process_name )
				m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_action_name, buf1);
			else buf1=_T("");

			name+=buf;
			if(buf1!=_T(""))
			{
				if(buf!=_T("")) name+=_T(" : ");
				name+=buf1;
			}
		}
		name+=_T(" ]");
	}
	return true;
}

bool CaplTaskTreeItem::RefreshItem()
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	
	if(!m_task || m_task->GetType()==0) return false;
	m_doc->m_wf_mgr.LoadTaskInfo(m_task);

	UINT ico= ICON_TASK;
	
	if(m_tree!=0)
	{
		
		CString name, buf, buf1;
		GetName(name);

		CString str;
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_state, str);
		UINT ico_state= 1, ico_prior= ICO_EFF_NO;
		if(str==_T("active") || str==_T("work") || str== _T("notify") ||  str== _T("wait")) ico_state++;
		else if(str==_T("suspend") )  ico_state+=2;
		else if(str==_T("cancel"))   ico_state+=3;
		else if(str==_T("complete")) ico_state+=4;		
		else if(str==_T("inactive") ) ico+=3;
		else if(str!=_T("work"))	 ico+=1;

		if(name!=_T("")) {if(name[0]==_T('&')) 
			ico= ICON_LOG_TASK;}
		
		CString prior;		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_act_inst_prior, prior);
		if(prior==_T("low")) ico_prior= ICO_EFF_LOW;
		else if(prior==_T("hight")) ico_prior= ICO_EFF_HIGH;
		else ico_prior= ICO_EFF_NORMAL;

		
		SetItemImage(ico_prior, IDX_IL_TREE_EFF);		
		SetItemImage(ico_state,IDX_IL_TREE_OBJ_STATE);
		SetItemImage(ico, IDX_IL_TREE_ITEM);

		if(m_bIsParent) SetItemImage(ICO_REL_WHERE_USED, IDX_IL_TREE_REL_TYPE);

		
		m_tree->SetItemText(m_item, name);


		// Выделяем цветом просроченные
		bool bWarning=false;
		if(m_doc->m_wf_mgr.GetItemColor(m_task,color,&bWarning)) {	if(bWarning) font_style|=APL_FONT_BOLD;	}
	}
	if(m_doc->m_tab_view->m_item_old==this) m_doc->ChangeItem(this);
	return true;
}

bool CaplTaskTreeItem::RefreshParentProcess()
{
	CaplTreeItem *parent=GetParentItem(this);
	if(0==parent) return false;

	if(parent->m_type!=APL_TREE_ITEM_PROCESS)  return false;
	parent->RefreshItem();
	((CaplProcessTreeItem*)parent)->GetProcessTasks();
	((CaplProcessTreeItem*)parent)->SortTask();
	parent->MyExpand();
	parent->RefreshAllChildItem();
	return true;
}


bool CaplTaskTreeItem::CreateTreeItem(HTREEITEM parent_item)
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	   
	CString name, buf, buf1;
	GetName(buf);

	UINT ico= ICON_TASK;

	InsetItem(buf,ico,parent_item);
	m_fictive_item=m_tree->InsertItem(_T("fictive"), 0, 0, m_item);

	m_expanded=false;

	RefreshItem();
	return true;
}

bool CaplTaskTreeItem::Expand(UINT action)
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	
	if(action==2)
	{
		m_tree->SetRedraw(FALSE);
		if(m_expanded) return true;
		if(m_hasSubItem) Expand(1);
		if(m_fictive_item!=0)
		{
			m_tree->DeleteItem(m_fictive_item);
			m_fictive_item=0;
		}
//		if(m_g_mode==APL_WF_SWOW_SP) ShowSubProcesses();
//		else if(m_g_mode==APL_WF_SHOW_WO) ShowWorkObjects();
		ShowSubProcesses();
		ShowWorkObjects();
		m_hasSubItem= true;
		m_expanded= true;
		m_tree->SetRedraw(TRUE);
		Sort();
	}
	else if(action==1)
	{
		CollapseItem();
		m_bProcShow= false;
		m_bPrevShow= false;
		m_sub_proc_items.Clear();
		m_work_obj_items.Clear();
	}
	return true;
}

void CaplTaskTreeItem::ShowProperties()
{
	_APL_TREE_ITEM_CHEK_PARAM_VOID
	if(m_doc->m_wf_mgr.LoadTaskInfo(m_task))
	{
		m_doc->m_wf_mgr.ShowTaskProperties(m_task);
		RefreshItem();
	}
}

bool CaplTaskTreeItem::ShowInListCtrl(CListCtrl *list)
{
	if(list==0) return false;
	else list->DeleteAllItems();
	if(m_doc==0)return false;
	if(m_doc->m_BShowInListCtrl==false) return true;
	
	CHECK_SHOW_LIST_CTRL(m_task);

	m_doc->m_wf_mgr.LoadTaskInfo(m_task);

	CString buf, buf1;
	int i= list->InsertItem(0,  APL_T("Обозначение:"));
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_action_id, buf);
	list->SetItemText(i, 1, buf);
	i= list->InsertItem(i+1,  APL_T("Наименование:"));
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_action_name, buf);
	list->SetItemText(i, 1, buf);
	i= list->InsertItem(i+1,  APL_T("Описание:"));
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_action_dscr, buf);
	list->SetItemText(i, 1, buf);

	i= list->InsertItem(i+1, _T(""));

	CaplInstance* inst= NULL;
	CaplAggr aggr;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, inst);
	if(inst)
	{
		m_doc->m_wf_mgr.LoadProcessInfo(inst);
		m_doc_data.GetAttr(inst, m_doc->m_wf_mgr.a_proc_owner, inst);
		if(inst)
		{
			i= list->InsertItem(i+1,  APL_T("Выдал:"));
			//m_doc->m_api.m_appr_mgr.GetPersonName(inst, buf);
			m_doc->m_api.GetItemName(inst, buf);
			if(m_doc->m_api.m_data.IsKindOf(inst,m_doc->m_api.m_appr_mgr.e_person))
			{
				CString sPhone;
				m_doc_data.GetAttr(inst, m_doc->m_api.m_appr_mgr.a_pers_phone, sPhone);
				if(sPhone!=_T("")){buf+=_T(" (тел.");buf+=sPhone; buf+=_T(")");}
			}
			list->SetItemText(i, 1, buf);
			list->SetItemData(i, (long)inst);
		}
	}

	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_performer, inst);
	if(inst)
	{
		i= list->InsertItem(i+1,  APL_T("Исполнитель:"));
		//m_doc->m_api.m_appr_mgr.GetPersonName(inst, buf);
		m_doc->m_api.GetItemName(inst, buf);
		if(m_doc->m_api.m_data.IsKindOf(inst,m_doc->m_api.m_appr_mgr.e_person))
		{
			CString sPhone;
			m_doc_data.GetAttr(inst, m_doc->m_api.m_appr_mgr.a_pers_phone, sPhone);
			if(sPhone!=_T("")){buf+=_T(" (тел.");buf+=sPhone; buf+=_T(")");}
		}
		list->SetItemText(i, 1, buf);
		list->SetItemData(i, (long)inst);
	}
	else
	{
		i= list->InsertItem(i+1,  APL_T("Координатор:"));
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_manager, inst);
		if(inst)
		{
			//m_doc->m_api.m_appr_mgr.GetPersonName(inst, buf);
			m_doc->m_api.GetItemName(inst, buf);
			list->SetItemText(i, 1, buf);
		}
	}
	i= list->InsertItem(i+1, _T(""));
	
	COleDateTime odt;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_act_inst_start_date, buf);
	if(!buf.IsEmpty())
	{
		i=list->InsertItem(i+1,  APL_T("Дата выдачи:"));
		aplString2Date(buf, odt);	
		buf= odt.Format(_T("%d.%m.%Y  %H:%M"));
		list->SetItemText(i, 1, buf);
	}
	if(m_doc->m_wf_mgr.a_task_notify_date)
	{
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_notify_date, buf);
		if(!buf.IsEmpty())
		{
			i=list->InsertItem(i+1,  APL_T("Дата получения:"));
			aplString2Date(buf, odt);	
			buf= odt.Format(_T("%d.%m.%Y  %H:%M"));
			list->SetItemText(i, 1, buf);
		}
	}
	if(m_doc->m_wf_mgr.a_task_reseave_date)
	{
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_reseave_date, buf);
		if(!buf.IsEmpty())
		{
			i=list->InsertItem(i+1,  APL_T("Дата подтверждения:"));
			aplString2Date(buf, odt);	
			buf= odt.Format(_T("%d.%m.%Y  %H:%M"));
			list->SetItemText(i, 1, buf);
		}
	}
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_act_inst_end_date, buf);
	if(buf.IsEmpty())
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_act_inst_finish_date, buf);
	if(!buf.IsEmpty())
	{
		i=list->InsertItem(i+1,  APL_T("Дата завершения:"));
		aplString2Date(buf, odt);	
		buf= odt.Format(_T("%d.%m.%Y  %H:%M"));
		list->SetItemText(i, 1, buf);
	}
	
	i=list->InsertItem(i+1, _T(""));
	
	double n;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_act_inst_percent, n);
	buf.Format(_T("%i"), (int)n);buf+=_T('%');
	i=list->InsertItem(i+1,  APL_T("Выполнено:"));
	list->SetItemText(i, 1, buf);
 	
	i=list->InsertItem(i+1, _T(""));
		
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_act_inst_prior, buf);
	if(buf==_T("low")) buf=  APL_T("Низкий");
	else if(buf==_T("medium")) buf=  APL_T("Обычный");
	else if(buf==_T("hight")) buf=  APL_T("Высокий");
	i=list->InsertItem(i+1,  APL_T("Приоритет:"));
	list->SetItemText(i, 1, buf);

	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_state, buf);
	if(buf==_T("inactive")) buf=  APL_T("Не выполняется");
	else if(buf==_T("active")) buf=  APL_T("Выдано");
	else if(buf==_T("notify")) buf=  APL_T("Выдано, исполнитель оповещен");
	else if(buf==_T("work")) buf=  APL_T("Выполняется");
	else if(buf==_T("suspend")) buf=  APL_T("Остановлено");
	else if(buf==_T("cancel")) buf=  APL_T("Отозвано");
	else if(buf==_T("complete")) buf=  APL_T("Выполнено");		
	i=list->InsertItem(i+1,  APL_T("Состояние:"));
	list->SetItemText(i, 1, buf);

	aplExtent ext;
	CStringArray  comment;
	
	comment.Add(_T("m_task"));
	ext.Add(m_task);
	
	ShowInstanceInfoInListCtrl(ext,list,&comment);


	return true;
}

void CaplTaskTreeItem::ShowCmd(long cmd)
{
	switch (cmd)
	{
	case ID_CREATE_DOC: CreateDocument(); break;
	case ID_CREATE_PRODUCT: CreateProduct(); break;
	case ID_SHOW_NOTES: ShowNotes(); break;
	}	
}

BOOL CaplTaskTreeItem::ShowToolBarButton(CCmdUI* pCmdUI)
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	
	if(m_task==0) return false;
	if(m_task->GetId()==0) return false;
	if(m_task->GetType()==0) return false;
	
	CString buf;
	BOOL bShow= FALSE;
	CaplInstance *user= m_doc->m_api.m_appr_mgr.GetCurrentPerson();

	CaplInstance* per= NULL;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_performer, per);
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_state, buf);

	if(user==per && buf==_T("work"))
	{
		bShow= TRUE;
	}

	switch(pCmdUI->m_nID)
	{
		case ID_CREATE_DOC: 
		case ID_CREATE_PRODUCT: 
		case ID_SHOW_NOTES:
		case ID_CREATE_NOTE:
			pCmdUI->Enable(bShow); return TRUE; break;
	}
	return FALSE;
}

bool CaplTaskTreeItem::TrackPopupMenu(CWnd* wnd, CPoint &point, UINT view_mode)
{
	if(!m_task || m_task->GetType()==0)
		return false;

	CMenu menu;  gSetPsmResourceHandle();
	VERIFY(menu.LoadMenu(IDR_TREE_CONTEXT_MENU));
// 	VERIFY(menu.LoadToolBar(IDR_MENU_ICONS));
	CaplMenu::Install(wnd); // 	VERIFY(CaplMenu::Install(wnd, ePopupMenu ));
    CMenu* pPopup = menu.GetSubMenu(INDEX_TASK_MENU);
    ASSERT(pPopup != NULL);
	if(pPopup==0) return false;

	if(m_task)
	{
		if(!m_doc->m_wf_mgr.IsItemLogicalElement(m_task))
		{
			AppendAddIn((CMenu*)pPopup);
			UpdateMenu((CMenu**)&pPopup, view_mode);
		}
	}
	
	CaplInstance* inst= NULL;
	CString buf;
	bool bRes;
	aplExtent extWO;
	
	//текущая дата
	COleDateTime odt;
	m_doc_data.NET_GetServerDateTime(odt);
	CString sCurDate;
	aplDate2String(odt, sCurDate);
	
	CaplInstance *CurPerson= m_doc->m_api.m_appr_mgr.GetCurrentPerson();

//	m_doc->m_wf_mgr.LoadTaskInfo(m_task);
	CaplInstance* proc, *proc_tmpl=0;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, proc);
	if(0!=proc)  m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_of_tmpl, proc_tmpl);
	CaplInstance* performer= NULL, *mgr= NULL, *owner= NULL, *procMgr= NULL;

	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_performer, performer);
	if(performer && m_doc->m_api.m_data.IsKindOf(performer, m_doc->m_api.m_appr_mgr.e_official))
	{
		CaplInstance* offPer= NULL;
		m_doc->m_api.m_data.GetAttr(performer, m_doc->m_api.m_appr_mgr.a_official_act_person, offPer);
		performer= offPer;
	}
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_manager, mgr);
	if(mgr && m_doc->m_api.m_data.IsKindOf(mgr, m_doc->m_api.m_appr_mgr.e_official))
	{
		CaplInstance* offPer= NULL;
		m_doc->m_api.m_data.GetAttr(mgr, m_doc->m_api.m_appr_mgr.a_official_act_person, offPer);
		mgr= offPer;
	}
	m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_owner, owner);
	if(owner && m_doc->m_api.m_data.IsKindOf(owner, m_doc->m_api.m_appr_mgr.e_official))
	{
		CaplInstance* offPer= NULL;
		m_doc->m_api.m_data.GetAttr(owner, m_doc->m_api.m_appr_mgr.a_official_act_person, offPer);
		owner= offPer;
	}
	m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_manager, procMgr);
	if(procMgr && m_doc->m_api.m_data.IsKindOf(procMgr, m_doc->m_api.m_appr_mgr.e_official))
	{
		CaplInstance* offPer= NULL;
		m_doc->m_api.m_data.GetAttr(procMgr, m_doc->m_api.m_appr_mgr.a_official_act_person, offPer);
		procMgr= offPer;
	}

	bool bEnableReComplete=false;

	if(m_doc->m_wf_mgr.IsItemLogicalElement(m_task))
	{
		pPopup->RemoveMenu(ID_TASK_START,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_TASK_SUSPEND,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_TASK_RESTART,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_TASK_COMPLETE,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_TASK_CREATE_MANY_PROC,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_TASK_RUN,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_TASK_SET_PERFORMER,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_CREATE_DOC,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_CREATE_PRODUCT,MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_CREATE_REFUSAL,MF_BYCOMMAND);

		pPopup->EnableMenuItem(ID_TASK_STOP_ALL_AND_GO, MF_BYCOMMAND | MF_GRAYED);		
		CString buf;
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_state, buf);
		if(buf==_T("wait"))
		{
			if(CurPerson=owner) pPopup->EnableMenuItem(ID_TASK_STOP_ALL_AND_GO, MF_BYCOMMAND | MF_ENABLED);		
		}
	}
	else
	{
		pPopup->RemoveMenu(ID_TASK_STOP_ALL_AND_GO,MF_BYCOMMAND);

		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_state, buf);
		if(buf==_T("inactive"))
		{
			pPopup->EnableMenuItem(ID_TASK_START, MF_BYCOMMAND | MF_GRAYED);		
			pPopup->EnableMenuItem(ID_TASK_SUSPEND, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_RESTART, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_COMPLETE, MF_BYCOMMAND | MF_GRAYED);		
			
			pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_CREATE_PRODUCT, MF_BYCOMMAND | MF_GRAYED);
		}
		else if(buf==_T("active") || buf==_T("notify"))
		{
			pPopup->EnableMenuItem(ID_TASK_RUN, MF_BYCOMMAND | MF_GRAYED);
			if(CurPerson!=performer)
			{
				pPopup->EnableMenuItem(ID_TASK_START, MF_BYCOMMAND | MF_GRAYED);
				if(CurPerson!=mgr)
					pPopup->EnableMenuItem(ID_TASK_COMPLETE, MF_BYCOMMAND | MF_GRAYED);	
			}
			
	//		pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
	//		pPopup->EnableMenuItem(ID_CREATE_PRODUCT, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_CREATE_MANY_PROC,MF_BYCOMMAND|MF_ENABLED);
		}
		else if(buf==_T("work"))
		{
			pPopup->EnableMenuItem(ID_TASK_RUN, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_START, MF_BYCOMMAND | MF_GRAYED);		
			if(CurPerson!=performer && CurPerson!=mgr)
				pPopup->EnableMenuItem(ID_TASK_COMPLETE, MF_BYCOMMAND | MF_GRAYED);	

			pPopup->EnableMenuItem(ID_TASK_CREATE_MANY_PROC,MF_BYCOMMAND|MF_ENABLED);
		}
		else if(buf==_T("suspend")) 
		{
			pPopup->ModifyMenu(ID_TASK_RUN, MF_BYCOMMAND|MF_STRING, ID_TASK_RUN,  APL_T("&Продолжить выполнение"));
			pPopup->EnableMenuItem(ID_TASK_START, MF_BYCOMMAND | MF_GRAYED);		
			pPopup->EnableMenuItem(ID_TASK_SUSPEND, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_COMPLETE, MF_BYCOMMAND | MF_GRAYED);	
			
			pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_CREATE_PRODUCT, MF_BYCOMMAND | MF_GRAYED);
		}
		else if(buf==_T("complete") || buf==_T("cancel"))
		{
			pPopup->EnableMenuItem(ID_TASK_RUN, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_SUSPEND, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_RESTART, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_COMPLETE, MF_BYCOMMAND | MF_GRAYED);	
			pPopup->EnableMenuItem(ID_TASK_START, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_CREATE_PRODUCT, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_CREATE_REFUSAL, MF_BYCOMMAND | MF_GRAYED);
		}

		if(CurPerson!=owner && CurPerson!=procMgr)
		{
			pPopup->EnableMenuItem(ID_TASK_RUN, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_TASK_SUSPEND, MF_BYCOMMAND | MF_GRAYED);
			//pPopup->EnableMenuItem(ID_TASK_COMPLETE, MF_BYCOMMAND | MF_GRAYED);	
			if(CurPerson!=mgr)
				pPopup->EnableMenuItem(ID_TASK_RESTART, MF_BYCOMMAND | MF_GRAYED);
		}
		else
		{
			if(buf==_T("complete") || buf==_T("cancel"))
			{
				CString state1;
				m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_state, state1);
				if(state1==_T("running")) bEnableReComplete=true;
			}
		}
		if((CurPerson!=performer) && (CurPerson!=owner))
		{
			pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_CREATE_PRODUCT, MF_BYCOMMAND | MF_GRAYED);
			pPopup->EnableMenuItem(ID_CREATE_REFUSAL, MF_BYCOMMAND | MF_GRAYED);
		}

		if(!(CurPerson==mgr && CurPerson!=performer))
		{
			pPopup->RemoveMenu(ID_TASK_SET_PERFORMER, MF_BYCOMMAND);
		}
	}

	if(bEnableReComplete) pPopup->EnableMenuItem(ID_TASK_RECOMPLETE, MF_BYCOMMAND | MF_ENABLED);	
	else pPopup->RemoveMenu(ID_TASK_RECOMPLETE,MF_BYCOMMAND);

	bool bEndTaskForce=false; // Завершать любым
	if(CurPerson==owner)
	{
		bool m_b_allow_owner_end_any_task=false;
		m_doc_data.GetAttr(proc_tmpl, m_doc->m_wf_mgr.a_proc_tmpl_allow_owner_end_any_task, m_b_allow_owner_end_any_task);
		if(m_b_allow_owner_end_any_task)
		{
			pPopup->EnableMenuItem(ID_TASK_COMPLETE, MF_BYCOMMAND | MF_ENABLED);	
			bEndTaskForce=true;
		}
	}
	
	//для запуска подпроцесса
//	CArray<CaplProcessTreeItem::CStPointsMenuInfo, CaplProcessTreeItem::CStPointsMenuInfo> stPoints;
//
//	if(user==per)// исполнитель
//	{
//		if(buf==_T("work") || buf==_T("active") || buf==_T("notify")) // состояние нормальное :))
//		{
//			CMenu* pSubPopup= NULL;
//			CaplInstance* activity;
//
//			aplExtent subProcs;
//			CaplWorkFlowManager* m_wf_mgr= &m_doc->m_wf_mgr;
//			CaplAPI* m_api= &m_doc->m_api;
//			
//			int m= 100;
//			CString sName;
//			
//			m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_activity, activity);
//			m_api->m_data.GetAttr(activity, m_wf_mgr->a_activity_sub_proc_tmpl, subProcs);
//			if(subProcs.GetSize())
//			{
//				pSubPopup= new CMenu;
//				pSubPopup->CreatePopupMenu();
//			
//				for(int i= 0; i<subProcs.GetSize(); i++)
//				{
//					m_api->GetItemName(subProcs[i], sName);
//					pSubPopup->InsertMenu(i, MF_BYPOSITION|MF_STRING, m, sName);
//					
//					CaplProcessTreeItem::CStPointsMenuInfo info(m, sName, subProcs[i]);
//					stPoints.Add(info);
//					m+=10;
//				}
//				pSubPopup->InsertMenu(0, MF_BYPOSITION|MF_STRING, ID_TASK_RUN, APL_T("Задание"));
//				pSubPopup->InsertMenu(1, MF_BYPOSITION|MF_SEPARATOR, 0, _T(""));
//
//				UINT state = pPopup->GetMenuState(ID_TASK_RUN, MF_BYCOMMAND);
//				if(state & MF_GRAYED)
//					pSubPopup->EnableMenuItem(ID_TASK_RUN, MF_BYCOMMAND|MF_GRAYED);
//				
//				pPopup->ModifyMenu(ID_TASK_RUN, MF_BYCOMMAND|MF_POPUP, (UINT)pSubPopup->GetSafeHmenu(), APL_T("Запустить..."));
//			}			
//		}
//	}
	
	BOOL res = pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
						point.x, point.y, wnd);
	
//	m_tree->SetRedraw(FALSE);
	switch (res)
	{
		case ID_CREATE_NOTE: CreateNote(); break;
		case ID_SHOW_NOTES: ShowNotes(); break;
		case ID_TASK_RUN:
			bRes= m_doc->m_wf_mgr.RunTask(m_task);
			if(bRes)
			{
				RefreshItem();
				RefreshParentProcess();
			}
			break;
		case ID_TASK_SUSPEND:
			bRes= m_doc->m_wf_mgr.SuspendTask(m_task);
			if(bRes)
			{
				RefreshItem();
				RefreshParentProcess();
			}
			break;
		case ID_TASK_RESTART:
			proc= m_doc->m_wf_mgr.RestartTask(m_task);
			if(proc)
			{
				RefreshItem();
				RefreshParentProcess();
			}
			break;
		case ID_TASK_COMPLETE:
			if(CurPerson==performer || CurPerson==owner)
			{
				bRes= m_doc->m_wf_mgr.EndTask(m_task,0,false,bEndTaskForce);
				if(bRes)
				{			
					RefreshItem();
					RefreshParentProcess();
				}
			}
			else if(CurPerson==mgr)
			{
				ShowProperties();
			}
			break;
		case ID_TASK_RECOMPLETE: // P
			if(CurPerson==performer || CurPerson==owner)
			{
				bRes= m_doc->m_wf_mgr.ReEndTask(m_task,0,false,bEndTaskForce);
				if(bRes)
				{			
					RefreshItem();
					RefreshParentProcess();
				}
			}
			break;

		case ID_TASK_SET_PERFORMER:
			if(CurPerson==mgr)
			{
				ShowProperties();
			}
			break;
		case ID_TASK_PROCESS:
			if(proc && !m_bProcShow)
			{
				CaplProcessTreeItem* item= new CaplProcessTreeItem(m_tree, m_doc, proc);
				item->CreateTreeItem(m_item);
				m_bProcShow= true;
				if(!m_expanded)
				{
					m_expanded= true;
					m_hasSubItem= true;
				}
				MyExpand();
			}
			break;
		case ID_PREVIOUS_TASK:
			m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_prev, inst);
			if(inst && !m_bPrevShow)
			{
				m_doc->m_wf_mgr.LoadTaskInfo(inst);
				CaplTaskTreeItem* item= new CaplTaskTreeItem(m_tree, m_doc, inst);
				item->CreateTreeItem(m_item);
				m_bPrevShow= true;
				if(!m_expanded)
				{
					m_expanded= true;
					m_hasSubItem= true;
				}
				MyExpand();
			}
			break;
		case ID_WORK_ITEMS:
			ShowWorkObjects();
			if(!m_expanded)
			{
				m_expanded= true;
				m_hasSubItem= true;
			}
			MyExpand();
			break;
		case ID_TASK_SUB_PROC:
			ShowSubProcesses();
			if(!m_expanded)
			{
				m_expanded= true;
				m_hasSubItem= true;
			}
			MyExpand();
			break;
		case ID_TASK_START:

			m_doc->m_wf_mgr.SetTaskWorking(m_task);
			RefreshItem();
			break;
		case ID_CREATE_DOC:
			if(m_doc->m_wf_mgr.CanChangeWorkObjectsList(proc))
			{
				if(CreateDocument())
				{
					ShowWorkObjects();
					if(!m_expanded)
					{
						m_expanded= true;
						m_hasSubItem= true;
					}
					MyExpand();
				}
			}
			break;
		case ID_CREATE_PRODUCT:
			if(m_doc->m_wf_mgr.CanChangeWorkObjectsList(proc))
			{
				if(CreateProduct())
				{
					ShowWorkObjects();
					if(!m_expanded)
					{
						m_expanded= true;
						m_hasSubItem= true;
					}
					MyExpand();
				}
			}
			break;
		case ID_CREATE_REFUSAL:
			if(m_doc->m_wf_mgr.CanChangeWorkObjectsList(proc))
			{
				if(CreateRefusal())
				{
					ShowWorkObjects();
					if(!m_expanded)
					{
						m_expanded= true;
						m_hasSubItem= true;
					}
					MyExpand();
				}
			}
			break;
		case ID_TASK_CREATE_MANY_PROC:
			{
				m_doc->m_wf_mgr.StartManyProcs(NULL, m_task);
				break;
					
			}
		case ID_SHOW_WF_TEMPL_SCHEMA:
			{
				CaplInstance *act=0;
				m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_activity, act);
				m_doc->m_wf_mgr.ShowTemplateSchema(0,act);
			}
			break;

		case ID_SHOW_PARENT_TASK:
			{
				ShowParentTasks();
			}
			break;
		case ID_SHOW_PARENT_PROCESS:
			{
				ShowParentProcess();
			}
			break;
		case ID_SS_COPY_DOCDISK:
			{
				static CString path;
				m_doc->m_api.m_folder_mgr.CopyDocOnDisk(m_task, path);
			}
			break;
		case ID_COPY_ITEMS_TO_FOLDER:
			{
				aplExtent ext;
				m_doc->m_api.m_wf_mgr->GetWorkObjects(m_task,ext);
				if(0==ext.GetSize()) AfxMessageBox(APL_T("Нет рабочих объектов!"),MB_OK|MB_ICONWARNING);
				else
				{
					CaplInstance *folder=m_doc->m_api.m_folder_mgr.SelectInstance(APL_MODE_SELECT_FOLDER,APL_T("Выберите папку для сохранения"));
					if(0!=folder) m_doc->m_api.m_folder_mgr.AddToFolder(folder,ext);
				}
			}
			break;

		case ID_TASK_STOP_ALL_AND_GO:
			{
				m_doc->m_wf_mgr.StopAllAddRunLogcalElement(m_task);
				RefreshItem();
				RefreshParentProcess();
			}
			break;
		default: 
			PrepareContextMenu(res); 
			break;
	}
	m_tree->SetRedraw();
	return true;
}

void CaplTaskTreeItem::ShowSubProcesses()
{
	_APL_TREE_ITEM_CHEK_PARAM_VOID
	if(!m_task || m_task->GetType()==0)
		return;

	m_tree->SetRedraw(FALSE);
	m_doc->m_wf_mgr.LoadTaskInfo(m_task);
	CaplAggr aggr;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_sub_proc, aggr);
	for(int i= 0; i<aggr.GetSize(); i++)
	{
		CaplInstance* inst= NULL;
		aggr.GetByIndex(i, inst);
		if(-1==m_sub_proc_items.Find(inst))
		{
			m_doc->m_wf_mgr.LoadProcessInfo(inst);
			CaplProcessTreeItem* item= new CaplProcessTreeItem(m_tree, m_doc, inst);
			item->CreateTreeItem(m_item);
			item->m_task= m_task;
			m_sub_proc_items.Add(inst);
		}
	}
	m_tree->SetRedraw(TRUE);
}

void CaplTaskTreeItem::ShowWorkObjects()
{
	_APL_TREE_ITEM_CHEK_PARAM_VOID
	if(!m_task || m_task->GetType()==0) return;
	
	int i;

	m_tree->SetRedraw(FALSE);
	if(m_task)
	{		
		CString buf;
		CaplInstance *user=m_doc->m_api.m_appr_mgr.GetCurrentPerson();

		CaplInstance* per= NULL;
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_performer, per);
		if(per && m_doc->m_api.m_data.IsKindOf(per, m_doc->m_api.m_appr_mgr.e_official))
		{
			CaplInstance* offPer= NULL;
			m_doc->m_api.m_data.GetAttr(per, m_doc->m_api.m_appr_mgr.a_official_act_person, offPer);
			per= offPer;
		}
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_state, buf);

		if(user==per && (buf==_T("active") || buf==_T("notify")))
		{
//			if(IDYES==MessageBox(NULL, APL_T("Подтвердить получение задания?"), 
//				APL_T("Уведомление о получении"), MB_YESNO|MB_ICONWARNING))
			{
				m_doc->m_wf_mgr.SetTaskWorking(m_task);
				RefreshItem();
			}
//			else return;
		}

		CaplInstance* proc= NULL;
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, proc);
		m_tree->SetRedraw(FALSE);
		if(proc)
		{ 
			m_doc->m_wf_mgr.LoadProcessInfo(proc);
			aplExtent aggr;
			m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);
			aplExtent ext;
			CaplInstance* inst= NULL, *inst1= NULL;
			bool bForNote;
			for(i= 0; i<aggr.GetSize(); i++)
			{
				inst1= aggr[i];				
				if(!inst1) continue;
				if(inst1->GetAccessmode()==aplNO) continue;
				
				m_doc_data.GetAttr(inst1, m_doc->m_wf_mgr.a_wo_object, inst);

				if(!inst) continue;
				if(inst->GetAccessmode()==aplNO) continue;
		
				ext.Add(inst);
			}
		
			m_doc->m_api.m_message_mgr.LoadExtentInfo(ext);

			for(i= 0; i<aggr.GetSize(); i++)
			{
				inst1= aggr[i];				
				if(!inst1) continue;
				if(inst1->GetAccessmode()==aplNO) continue;
				
				m_doc_data.GetAttr(inst1, m_doc->m_wf_mgr.a_wo_object, inst);
				m_doc_data.GetAttr(inst1, m_doc->m_wf_mgr.a_wo_for_note, bForNote);

				if(!inst) continue;
				if(inst->GetAccessmode()==aplNO) continue;
				
				CaplTreeItem* aplItem= NULL;
				InsertInstInTree(inst, m_item, m_doc, m_tree, m_work_obj_items, NULL, &aplItem, NULL, bForNote);
			}
		}//if(proc)
	}
	m_tree->SetRedraw(TRUE);
}

bool CaplTaskTreeItem::PasteItem(CaplTreeItem *item, CPoint *point)
{
	if(item==0) return false;
	if(m_tree==0) return false;
	if(m_doc==0) return false;
	if(!m_task || m_task->GetType()==0) return false;

	CaplInstance *user= m_doc->m_api.m_appr_mgr.GetCurrentPerson();
	CaplInstance* per= NULL, *manager= NULL, *owner= NULL, *process= NULL;

	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, process);
	m_doc_data.GetAttr(process, m_doc->m_wf_mgr.a_proc_owner, owner);
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_performer, per);
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_manager, manager);

	if(user!=owner && !aplIsPersonOrgElement(&m_doc->m_api, per, user) &&
		!aplIsPersonOrgElement(&m_doc->m_api, manager, user))
	{
		AfxMessageBox(APL_T("У Вас нет прав для добавления объекта в задание!"),MB_ICONSTOP|MB_OK);
		return false;
	}

	CaplAggr aggr;
	CaplInstance* proc= NULL;
	if(m_task)
	{
		CString buf;
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_state, buf);
		if(buf==_T("active") || buf==_T("notify"))
		{
//			if(IDYES==MessageBox(NULL, APL_T("Подтвердить получение задания?"), 
//				APL_T("Уведомление о получении"), MB_YESNO|MB_ICONWARNING))
			{
				m_doc->m_wf_mgr.SetTaskWorking(m_task);
				RefreshItem();
			}
		}
		if(buf!=_T("work"))
		{
			AfxMessageBox(APL_T("Добавлять объекты можно только в выполняющееся задание!"),MB_ICONSTOP|MB_OK);
			return false;
		}
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, proc);
		if(!proc) return false;
		m_doc->m_wf_mgr.LoadProcessInfo(proc);
		m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);
	}
	else return false;
	
	CaplInstance* inst= NULL;
	if(item->m_type== APL_TREE_ITEM_PROCESSTMPL || item->m_type==APL_TREE_ITEM_PROCESS)
	{
		aplExtent ext;
		item->GetAccessedInstances(ext);
		if(ext.GetSize())
			return CreateSubprocess(ext[0]);
		return false;
	}
	else if(item->m_type==APL_TREE_ITEM_PRODUCT)
	{
		inst=((CaplProductTreeItem*)item)->m_pdf;
		if(inst==0) inst=((CaplProductTreeItem*)item)->m_prd;
		if(inst==0) return false;
	}
	else if(item->m_type==APL_TREE_ITEM_DOCUMENT)
	{
		if(0!=((CaplDocTreeItem*)item)->m_rev) inst=((CaplDocTreeItem*)item)->m_rev;
		else inst=((CaplDocTreeItem*)item)->m_inst;
		if(inst==0) return false;
	}
	else if(item->m_type==APL_TREE_ITEM_CHANGE)
	{
		inst= ((CaplChangeTreeItem*)item)->m_chng;
		if(inst==0) return false;
	}
	else if(item->m_type==APL_TREE_ITEM_BP)
	{

		inst= ((CaplBPTreeItem*)item)->m_inst;
		if(inst==0) return false;
	}
	else if(item->m_type==APL_TREE_ITEM_REFUSAL)
	{

		inst= ((CaplRefusalTreeItem*)item)->m_refusal;
		if(inst==0) return false;

		CMenu menu;  gSetPsmResourceHandle();
		CMenu *pPopup;
		VERIFY(menu.LoadMenu(IDR_PASTE_ITEM_MENU1));
		CaplMenu::Install(m_tree); 
		pPopup = menu.GetSubMenu(0);

		if(pPopup!=0)
		{
			POINT pnt;
			if(point==0)
			{
				RECT rect;
				m_tree->GetItemRect(m_item,&rect,TRUE);
				m_tree->ClientToScreen(&rect);
				pnt.x=rect.right;
				pnt.y=rect.bottom;
			}
			else
			{
				pnt.x=point->x;
				pnt.y=point->y;
			}

			HTREEITEM parent = m_tree->GetNextItem(item->m_item,TVGN_PARENT);
			CaplTreeItem *parent_item = (CaplTreeItem*)m_tree->GetItemData(parent);
			if(parent_item && parent_item->m_type==APL_TREE_ITEM_QUERY)
			{
				pPopup->EnableMenuItem(ID_DOCUMENT_MOVE, MF_BYCOMMAND|MF_GRAYED);
			}
			BOOL res=pPopup->TrackPopupMenu(TPM_LEFTALIGN|
				TPM_RIGHTBUTTON|TPM_RETURNCMD,pnt.x,pnt.y,m_tree);

			if(ID_CREATE_COPY_REFUSAL==res)return CreateRefusal(inst);
			else if(ID_INSERT_REF!=res) return false;
		}

	}
	else if(item->m_type!=APL_TREE_ITEM_TASK && item->m_type!=APL_TREE_ITEM_PROCESS && 
		item->m_type!=APL_TREE_ITEM_PROCESSTMPL && item->m_type!=APL_TREE_ITEM_ACTIVITY)
	{
		aplExtent ext;
		item->GetAccessedInstances(ext);//??????
		if(!ext.GetSize()) return false;

		inst= ext[0];
	}



	bool bIsNew= true;
	for(int i= 0; i<aggr.GetSize(); i++)
	{
		CaplInstance* wo= NULL;
		CaplInstance* w_item= NULL;
		aggr.GetByIndex(i, wo);
		if(wo)
			m_doc_data.GetAttr(wo, m_doc->m_wf_mgr.a_wo_object, w_item);
		if(inst==w_item) bIsNew= false;
	}
	if(bIsNew)
	{
		if(!m_doc->m_wf_mgr.CanChangeWorkObjectsList(proc))
		{
			AfxMessageBox(APL_T("У Вас нет прав для изменения списка рабочих объектов!"),MB_ICONSTOP|MB_OK);
			return false;
		}

		CaplInstance* wo= m_doc_data.CreateInstance(m_doc->m_wf_mgr.e_wo);
		if(wo)
		{
			m_doc_data.PutAttr(wo, m_doc->m_wf_mgr.a_wo_object, inst);
			m_doc_data.PutAttr(wo, m_doc->m_wf_mgr.a_wo_action, m_task);

			aggr.Add(wo);
			
			m_doc_data.PutAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);

			bool bAddWO= false;
			CaplInstance* activity= NULL;
			m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_activity, activity);
			if(activity)
				m_doc_data.GetAttr(activity, m_doc->m_wf_mgr.a_activity_add_wo, bAddWO);
			if(bAddWO)
			{
				CaplAttrValue val[3];
				aplExtent ext;
				CaplInstance* process= NULL;
				m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, process);

				val[0].value.Set(process);
				val[0].attr= m_doc->m_wf_mgr.a_task_sub_proc;
				m_doc_data.NET_FindInstancesWithAttrValues(m_doc->m_wf_mgr.e_task, 1, &val[0], ext, false);

				if(ext.GetSize()>0)
				{
					m_doc->m_wf_mgr.LoadTaskInfo(ext);
					CaplInstance* up_level_proc= NULL;
					aplExtent objExt;
					m_doc_data.GetAttr(ext[0], m_doc->m_wf_mgr.a_task_proc, up_level_proc);

					CaplInstance*new_wo= m_doc->m_api.m_data.CreateInstance(m_doc->m_wf_mgr.e_wo);
					if(new_wo)
					{
						m_doc_data.PutAttr(new_wo, m_doc->m_wf_mgr.a_wo_object, inst);
						m_doc_data.PutAttr(new_wo, m_doc->m_wf_mgr.a_wo_for_note, false);
						m_doc_data.PutAttr(new_wo, m_doc->m_wf_mgr.a_wo_action, up_level_proc);

						m_doc_data.GetAttr(up_level_proc, m_doc->m_wf_mgr.a_proc_wo, objExt);
						objExt.Add(new_wo);
						m_doc_data.PutAttr(up_level_proc, m_doc->m_wf_mgr.a_proc_wo, objExt);
					}				
				}
			}

			m_doc_data.NET_SaveChanges();
			if(m_expanded)	ShowWorkObjects();
			else MyExpand(true);
		}
	}
	return true;
}

bool CaplTaskTreeItem::CreateSubprocess(CaplInstance* proc_or_tmpl)
{
	if(!proc_or_tmpl) return false;

	CaplAPI* api= &m_doc->m_api;
	
	CaplInstance *process_tmpl= NULL, *activity= NULL;
	aplExtent ext;

	int iVal;
	api->m_options_mgr.GetOptionValueBN( APL_NO_T("Настройка Workflow\\Не давать запускать подпроцессы, не указанные в настройке действия"), iVal, 0);	

	if(api->m_data.IsKindOf(proc_or_tmpl, m_doc->m_wf_mgr.e_proc))
	{
		if(IDNO==AfxMessageBox( APL_T("Поместить процесс в список подпроцессов задания?"), MB_YESNO|MB_ICONQUESTION))
			return false;

		if(iVal==1)
		{
			api->m_data.GetAttr(proc_or_tmpl, m_doc->m_wf_mgr.a_proc_of_tmpl, process_tmpl);
			api->m_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_activity, activity);
			api->m_data.GetAttr(activity, m_doc->m_wf_mgr.a_activity_sub_proc_tmpl, ext);
			
			if(-1==ext.Find(process_tmpl))
			{
				AfxMessageBox( APL_T("Шаблон процесса не задан как возможный подпроцесс выбранного задания."), MB_OK|MB_ICONERROR);
				return false;
			}
		}

		api->m_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_sub_proc, ext);
		ext.Add(proc_or_tmpl);
		api->m_data.PutAttr(m_task, m_doc->m_wf_mgr.a_task_sub_proc, ext);
		api->SaveChanges();
	}
	else if(api->m_data.IsKindOf(proc_or_tmpl, m_doc->m_wf_mgr.e_proc_tmpl))
	{
		if(IDNO==AfxMessageBox( APL_T("Создать подпроцесс задания?"), MB_YESNO|MB_ICONQUESTION))
			return false;

		if(iVal==1)
		{
			process_tmpl= proc_or_tmpl;
			api->m_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_activity, activity);
			api->m_data.GetAttr(activity, m_doc->m_wf_mgr.a_activity_sub_proc_tmpl, ext);
			
			if(-1==ext.Find(process_tmpl))
			{
				AfxMessageBox( APL_T("Шаблон процесса не задан как возможный подпроцесс выбранного задания."), MB_OK|MB_ICONERROR);
				return false;
			}
		}
		
		m_doc->m_wf_mgr.StartManyProcs(proc_or_tmpl, m_task);
	}
	
	if(!m_expanded)MyExpand();
	else ShowSubProcesses();
	
	m_tree->SetRedraw();

	return true;
}
 
bool CaplTaskTreeItem::CreateDocument()
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	if(m_task==0) return false;
	if(m_task->GetType()==0) return false;
	
	CaplInstance* doc=m_doc->m_api.m_doc_mgr.CreateDocument(_T(""), 0, 0, 0, _T(""));
	if(doc==0) return false;
	/*
	if(CaplTreeItem::m_AutoUzurpireDoc)
	{
		aplExtent ext; 
		ext.Add(doc);
		m_doc_data.NET_BecomeInstancesOwner(&ext);
	}*/

	CaplInstance* proc= NULL;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, proc);
	if(!proc) return false;
	m_doc->m_wf_mgr.LoadProcessInfo(proc);
	CaplAggr aggr;			
	m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);
	CaplInstance* wo= m_doc_data.CreateInstance(m_doc->m_wf_mgr.e_wo);
	if(wo)
	{
		m_doc_data.PutAttr(wo, m_doc->m_wf_mgr.a_wo_object, doc);
		m_doc_data.PutAttr(wo, m_doc->m_wf_mgr.a_wo_action, m_task);

		aggr.Add(wo);
		
		m_doc_data.PutAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);
		m_doc_data.NET_SaveChanges();
	}
	return true;
}

bool CaplTaskTreeItem::CreateProduct()
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	
	if(m_task==0) return false;
	if(m_task->GetType()==0) return false;
	
	CaplInstance *tmp_prd, *tmp_inst = m_doc->m_api.m_prd_mgr.CreateProduct(NULL, aplModeCreateProduct);
	if(tmp_inst!=0)
	{
		m_doc_data.GetAttr(tmp_inst, m_doc->m_api.m_prd_mgr.a_pdf_prd, tmp_prd);
		
		CaplInstance* proc= NULL;
		m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, proc);
		if(!proc) return false;
		m_doc->m_wf_mgr.LoadProcessInfo(proc);
		CaplAggr aggr;			
		m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);
		CaplInstance* wo= m_doc_data.CreateInstance(m_doc->m_wf_mgr.e_wo);
		if(wo)
		{
			m_doc_data.PutAttr(wo, m_doc->m_wf_mgr.a_wo_object, tmp_prd);
			m_doc_data.PutAttr(wo, m_doc->m_wf_mgr.a_wo_action, m_task);
			
			aggr.Add(wo);
			
			m_doc_data.PutAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);
			m_doc_data.NET_SaveChanges();
		}
	}
	return true;
}

bool CaplTaskTreeItem::CreateRefusal(CaplInstance *baserefusal)
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL

	if(m_task->GetType()==0) return false;
	//CaplInstance *refusalt=m_doc->m_api.m_expl_mgr->CreateRefusal();
	aplExtent ext;
	CaplInstance *refusal=m_doc->m_fault_mgr.CreateRefusal(0,ext,0,baserefusal);
	if(0==refusal) return false;
	
	CaplInstance* proc= NULL;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, proc);
	if(!proc) return false;
	m_doc->m_wf_mgr.LoadProcessInfo(proc);
	aplExtent aggr;			
	m_doc_data.GetAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);
	CaplInstance* wo= m_doc_data.CreateInstance(m_doc->m_wf_mgr.e_wo);
	if(wo)
	{
		m_doc_data.PutAttr(wo, m_doc->m_wf_mgr.a_wo_object, refusal);
		m_doc_data.PutAttr(wo, m_doc->m_wf_mgr.a_wo_action, m_task);

		aggr.Add(wo);

		m_doc_data.PutAttr(proc, m_doc->m_wf_mgr.a_proc_wo, aggr);
		m_doc_data.NET_SaveChanges();
	}

	m_doc->m_fault_mgr.UpdateRefusalInfoInWF(refusal,0);

	// Проверяем наличие документов в задании
	int i;
	CaplInstance *inst;
	aplExtent ext_doc;
	bool bNeedQuesion4Doc=false;

	m_doc->m_api.LoadExtentInfo(aggr);
	for(i=0;i<aggr.GetSize();i++)
	{
		m_doc_data.GetAttr(aggr[i], m_doc->m_wf_mgr.a_wo_object, inst);
		if(0==inst) continue;
		if(inst->IsDeleted()) continue;
		if(m_doc->m_api.m_data.IsKindOf(inst,m_doc->m_api.m_doc_mgr.e_doc)) ext_doc.Add(inst);
	}
	if(ext_doc.GetSize()<=0) return true;
	if(IDYES!=AfxMessageBox(APL_T("Скопировать документы процесса в описание неисправности?"),MB_YESNO|MB_ICONQUESTION)) return true;

	m_doc->m_api.m_AutoSave=false;
	for(i=0;i<ext_doc.GetSize();i++)
	{
		m_doc->m_api.m_doc_mgr.CreateAssociation(refusal,ext_doc[i]);
	}
	m_doc->m_api.m_AutoSave=true;
	m_doc_data.NET_SaveChanges();
	return true;
}



void CaplTaskTreeItem::GetAccessedInstances(aplExtent &ext)
{
	ext.Clear();
	if(m_task){if(m_task->GetType()!=0)ext.Add(m_task);}
}



bool CaplTaskTreeItem::ShowParentProcess()
{
	CaplInstance *process;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, process);
	if(0==process) return false;

	aplExtent ext;
	m_doc->m_wf_mgr.GetParentTasks(process,ext);
	if(0==ext.GetSize()) {AfxMessageBox(APL_T("Процесс не является подпроцессом")); return true;}
	m_doc->m_wf_mgr.LoadTaskInfo(ext);
	int i;
	for(i=0;i<ext.GetSize();i++)
	{
		CaplInstance *task=ext[i];
		if(0==task) continue;
		CaplInstance *proc;
		m_doc_data.GetAttr(task, m_doc->m_wf_mgr.a_task_proc, proc);
		if(0==proc) continue;

		CaplProcessTreeItem* item= new CaplProcessTreeItem(m_tree, m_doc, proc);
		item->m_bIsParent=true;
		item->CreateTreeItem(m_item);
	}
	MyExpand(false);
	return true;
}
bool CaplTaskTreeItem::ShowParentTasks()
{
	//Expand(2);
	CaplInstance *process;
	m_doc_data.GetAttr(m_task, m_doc->m_wf_mgr.a_task_proc, process);
	if(0==process) return false;

	aplExtent ext;
	m_doc->m_wf_mgr.GetParentTasks(process,ext);
	if(0==ext.GetSize()) {AfxMessageBox(APL_T("Процесс не является подпроцессом")); return true;}

	m_doc->m_wf_mgr.LoadTaskInfo(ext);
	int i;
	for(i=0;i<ext.GetSize();i++)
	{
		CaplInstance *task=ext[i];

		CaplTaskTreeItem* item= new CaplTaskTreeItem(m_tree, m_doc, task);
		item->m_bIsParent=true;
		item->CreateTreeItem(m_item);

	}
	MyExpand(false);
	return true;
}
