// m_api->m_prd_inst_mgr.cpp

#include "stdafx.h"
#include "dictionary.h"
#include "apl_api.h"
#include "ManufActionDlg.h"
#include "CheckOutDlg.h"
#include "CheckInDlg.h"
#include "DisAsmStatusDlg.h"
#include "Choose_sub_bps_dlg.h" 
#include "ApplyToAll.h" 
#include "BPResDlg.h"
#include "BPInstDlg.h"
#include "DocChanges.h"
#include "choose_inst_dlg.h"

bool CaplBPManager::m_bShowId=true;
bool CaplBPManager::m_bShowName=true;
bool CaplBPManager::m_bShowType=true;
bool CaplBPManager::m_bRecursive=true;
bool CaplBPManager::m_bCheckUniqs=true;
CDisAsmStatusDlg m_status_dlg;

bool CaplBPManager::Attach(CaplAPI *api)
{
	if(api==0) {Detach();return false;}
	CaplStepManager::Attach(api);

	m_status_dlg_created=false;
	m_status_count=0;
	m_apply_to_all=false;
	m_undo_check_out=false;
	m_level=0;

	a_bp_type=0;
	
	e_bp_type=m_data->GetEntityBN(_T("apl_business_process_type"));
	a_bp_type_name=m_data->GetAttrDefinition(e_bp_type,S::name);

	e_bp=m_data->GetEntityBN(_T("apl_business_process"));
	a_bp_id=m_data->GetAttrDefinition(e_bp,S::id);
	a_bp_name=m_data->GetAttrDefinition(e_bp,S::name);
	a_bp_descr=m_data->GetAttrDefinition(e_bp,S::description);
	a_bp_code=m_data->GetAttrDefinition(e_bp,S::code);
	a_bp_elements=m_data->GetAttrDefinition(e_bp,_T("elements"));
	a_bp_type=m_data->GetAttrDefinition(e_bp,_T("type"));
	a_bp_lock=m_data->GetAttrDefinition(e_bp,_T("locker"));
	a_bp_act=m_data->GetAttrDefinition(e_bp,_T("active_version"));
	a_bp_res=m_data->GetAttrDefinition(e_bp,_T("resources"));
	a_bp_parent=m_data->GetAttrDefinition(e_bp,_T("main_parent"));
	a_bp_label=m_data->GetAttrDefinition(e_bp,_T("label"));
	a_bp_state=m_data->GetAttrDefinition(e_bp,_T("state"));
	a_bp_guid = m_data->GetAttrDefinition(e_bp, _T("guid"));
	a_bp_date_time = m_data->GetAttrDefinition(e_bp, _T("date_time"));
	a_bp_customized = m_data->GetAttrDefinition(e_bp, _T("customized"));
	a_bp_optional = m_data->GetAttrDefinition(e_bp, _T("optional"));
	a_bp_source = m_data->GetAttrDefinition(e_bp, _T("source"));

	a_bp_org= m_data->GetAttrDefinition(e_bp, _T("organization"));
	a_bp_class= m_data->GetAttrDefinition(e_bp, _T("class"));
	a_bp_percentage_of_otk= m_data->GetAttrDefinition(e_bp, _T("percentage_of_otk"));
	a_bp_number_of_simultaneously_processed_parts= m_data->GetAttrDefinition(e_bp, _T("number_of_simultaneously_processed_parts"));
	a_bp_t_sht= m_data->GetAttrDefinition(e_bp, _T("t_sht"));
	a_bp_t_pz= m_data->GetAttrDefinition(e_bp, _T("t_pz"));
	a_bp_coat= m_data->GetAttrDefinition(e_bp, _T("coat"));
	a_bp_directive= m_data->GetAttrDefinition(e_bp, _T("directive"));

	e_bp_rel=m_data->GetEntityBN(_T("apl_business_process_relation"));
	a_bp_rel_id = m_data->GetAttrDefinition(e_bp_rel, _T("id"));
	a_bp_rel_name = m_data->GetAttrDefinition(e_bp_rel, _T("name"));
	a_bp_rel_descr = m_data->GetAttrDefinition(e_bp_rel, _T("description"));
	a_bp_rel_from = m_data->GetAttrDefinition(e_bp_rel, _T("from"));
	a_bp_rel_to = m_data->GetAttrDefinition(e_bp_rel, _T("to"));

	e_bp_ref=m_data->GetEntityBN(_T("apl_business_process_reference"));
	a_bp_ref_item=m_data->GetAttrDefinition(e_bp_ref,S::item);
	a_bp_ref_process=m_data->GetAttrDefinition(e_bp_ref,_T("assigned_process"));
	a_bp_ref_id=m_data->GetAttrDefinition(e_bp_ref,S::id);
	a_bp_ref_name=m_data->GetAttrDefinition(e_bp_ref,S::name);
	a_bp_ref_ranking=m_data->GetAttrDefinition(e_bp_ref,_T("ranking"));
	a_bp_ref_ranking_rat=m_data->GetAttrDefinition(e_bp_ref,_T("ranking_rationale"));
	a_bp_ref_frames_of_reference=m_data->GetAttrDefinition(e_bp_ref,_T("apl_frames_of_reference"));
	a_bp_ref_zagotov=m_data->GetAttrDefinition(e_bp_ref,_T("zagotov"));
	a_bp_ref_guid = m_data->GetAttrDefinition(e_bp_ref, _T("guid"));

	e_bp_res=m_data->GetEntityBN(_T("apl_business_process_resource"));
	a_bp_res_id=m_data->GetAttrDefinition(e_bp_res,S::id);
	a_bp_res_name=m_data->GetAttrDefinition(e_bp_res,S::name);
	a_bp_res_descr=m_data->GetAttrDefinition(e_bp_res,S::description);
	a_bp_res_type=m_data->GetAttrDefinition(e_bp_res,_T("type"));
	a_bp_res_object=m_data->GetAttrDefinition(e_bp_res,_T("object"));
	a_bp_res_process=m_data->GetAttrDefinition(e_bp_res,_T("process"));
	a_bp_res_val=m_data->GetAttrDefinition(e_bp_res,S::value_component);
	a_bp_res_unit=m_data->GetAttrDefinition(e_bp_res,S::unit_component);
	a_bp_res_derive_val=m_data->GetAttrDefinition(e_bp_res,_T("derive_value_component"));
	a_bp_res_derive_unit=m_data->GetAttrDefinition(e_bp_res,_T("derive_unit_component"));
	a_bp_res_assortment=m_data->GetAttrDefinition(e_bp_res,_T("apl_assortment"));
	a_bp_res_ranking=m_data->GetAttrDefinition(e_bp_res,_T("ranking"));
	a_bp_res_ranking_rationale=m_data->GetAttrDefinition(e_bp_res,_T("ranking_rationale"));

	e_bp_res_type=m_data->GetEntityBN(_T("apl_business_process_resource_type"));
	a_bp_res_type_name=m_data->GetAttrDefinition(e_bp_res_type,S::name);

	e_apl_bp_ver=m_data->GetEntityBN(_T("apl_business_process_version"));
	a_bp_ver_bp=m_data->GetAttrDefinition(e_apl_bp_ver,_T("process"));
	a_bp_ver_id=m_data->GetAttrDefinition(e_apl_bp_ver,S::id);
	a_bp_ver_name=m_data->GetAttrDefinition(e_apl_bp_ver,S::name);
	a_bp_ver_descr=m_data->GetAttrDefinition(e_apl_bp_ver,S::description);
	a_bp_ver_code=m_data->GetAttrDefinition(e_apl_bp_ver,S::code);
	a_bp_ver_type=m_data->GetAttrDefinition(e_apl_bp_ver,_T("type"));
	a_bp_ver_author=m_data->GetAttrDefinition(e_apl_bp_ver,_T("author"));
	a_bp_ver_start=m_data->GetAttrDefinition(e_apl_bp_ver,_T("start_date"));
	a_bp_ver_end=m_data->GetAttrDefinition(e_apl_bp_ver,_T("end_date"));
	a_bp_ver_num=m_data->GetAttrDefinition(e_apl_bp_ver,_T("number"));
	a_bp_ver_elements=m_data->GetAttrDefinition(e_apl_bp_ver,_T("elements"));
	a_bp_ver_base=m_data->GetAttrDefinition(e_apl_bp_ver,_T("base"));
	a_bp_ver_res=m_data->GetAttrDefinition(e_apl_bp_ver,_T("resources"));
	a_bp_ver_label=m_data->GetAttrDefinition(e_apl_bp_ver,_T("label"));
	a_bp_ver_char_val_versions=m_data->GetAttrDefinition(e_apl_bp_ver,_T("characteristic_value_versions"));
	a_bp_ver_basis=m_data->GetAttrDefinition(e_apl_bp_ver,_T("basis"));
	a_bp_ver_guid= m_data->GetAttrDefinition(e_apl_bp_ver,_T("guid"));
	a_bp_ver_customized= m_data->GetAttrDefinition(e_apl_bp_ver,_T("customized"));
	a_bp_ver_optional= m_data->GetAttrDefinition(e_apl_bp_ver,_T("optional"));

	a_bp_ver_org= m_data->GetAttrDefinition(e_apl_bp_ver, _T("organization"));
	a_bp_ver_class= m_data->GetAttrDefinition(e_apl_bp_ver, _T("class"));
	a_bp_ver_percentage_of_otk= m_data->GetAttrDefinition(e_apl_bp_ver, _T("percentage_of_otk"));
	a_bp_ver_number_of_simultaneously_processed_parts= m_data->GetAttrDefinition(e_apl_bp_ver, _T("number_of_simultaneously_processed_parts"));
	a_bp_ver_t_sht= m_data->GetAttrDefinition(e_apl_bp_ver, _T("t_sht"));
	a_bp_ver_t_pz= m_data->GetAttrDefinition(e_apl_bp_ver, _T("t_pz"));
	a_bp_ver_coat= m_data->GetAttrDefinition(e_apl_bp_ver, _T("coat"));
	a_bp_ver_directive= m_data->GetAttrDefinition(e_apl_bp_ver, _T("directive"));


	e_apl_bp_inst=m_data->GetEntityBN(_T("apl_business_process_instance"));	
	a_bp_inst_id=m_data->GetAttrDefinition(e_apl_bp_inst,S::id);
	a_bp_inst_name=m_data->GetAttrDefinition(e_apl_bp_inst,S::name);
	a_bp_inst_descr=m_data->GetAttrDefinition(e_apl_bp_inst,S::description);
	a_bp_inst_process=m_data->GetAttrDefinition(e_apl_bp_inst,_T("process"));	
	a_bp_inst_elements=m_data->GetAttrDefinition(e_apl_bp_inst,_T("elements"));
	a_bp_inst_res=m_data->GetAttrDefinition(e_apl_bp_inst,_T("resources"));
	a_bp_inst_date_time=m_data->GetAttrDefinition(e_apl_bp_inst,_T("date_time"));
	a_bp_inst_state=m_data->GetAttrDefinition(e_apl_bp_inst,_T("new_state"));
	a_bp_inst_end_datetime=m_data->GetAttrDefinition(e_apl_bp_inst,_T("end_date"));
	a_bp_inst_basis=m_data->GetAttrDefinition(e_apl_bp_inst,_T("basis"));
	a_bp_inst_duration=m_data->GetAttrDefinition(e_apl_bp_inst,_T("duration"));
	a_bp_inst_guid=m_data->GetAttrDefinition(e_apl_bp_inst,_T("guid"));
	
	e_bp_inst_ref=m_data->GetEntityBN(_T("apl_business_process_instance_reference"));	 
	a_bp_inst_ref_item=m_data->GetAttrDefinition(e_bp_inst_ref,_T("item"));
	a_bp_inst_ref_process=m_data->GetAttrDefinition(e_bp_inst_ref,_T("assigned_process_instance"));
	a_bp_inst_ref_id=m_data->GetAttrDefinition(e_bp_inst_ref,S::id);
	a_bp_inst_ref_name=m_data->GetAttrDefinition(e_bp_inst_ref,S::name);
	a_bp_inst_ref_frames_of_reference=m_data->GetAttrDefinition(e_bp_inst_ref,_T("apl_frames_of_reference"));
	a_bp_inst_ref_guid = m_data->GetAttrDefinition(e_bp_inst_ref, _T("guid"));

	return true;
}
// *************************************************************************
void CaplBPManager::Detach()
{
	m_data=0;
	e_bp=0; e_bp=0;
	a_bp_id=0; a_bp_name=0; a_bp_descr=0; a_bp_elements=0;a_bp_type=0;
	a_bp_guid=0;
	a_bp_date_time = NULL;


	a_bp_org=0;
	a_bp_class=0;
	a_bp_percentage_of_otk=0;
	a_bp_number_of_simultaneously_processed_parts=0;
	a_bp_t_sht=0;
	a_bp_t_pz=0;
	a_bp_coat=0;
	a_bp_directive=0;
	a_bp_customized=0;
	a_bp_optional=0;
	a_bp_source=0;
		
	e_bp_type=0;
	a_bp_type_name=0;

	e_bp_ref=0;
	a_bp_ref_item=0; a_bp_ref_process=0; a_bp_ref_id=0; a_bp_ref_name=0;
	a_bp_ref_ranking=0; a_bp_ref_ranking_rat=0;a_bp_ref_zagotov=0;

	e_bp_res=0;
	a_bp_res_id=0; a_bp_res_name=0; a_bp_res_descr=0; a_bp_res_type=0;
	a_bp_res_object=0; a_bp_res_val=0; a_bp_res_unit=0; a_bp_res_process=0;
	a_bp_res_derive_val=0; a_bp_res_derive_unit=0; a_bp_res_assortment=0;

	e_bp_res_type=0;
	a_bp_res_type_name=0;
	
	a_bp_ver_guid= 0;
	a_bp_ver_org=0;
	a_bp_ver_class=0;
	a_bp_ver_percentage_of_otk=0;
	a_bp_ver_number_of_simultaneously_processed_parts=0;
	a_bp_ver_t_sht=0;
	a_bp_ver_t_pz=0;
	a_bp_ver_coat=0;
	a_bp_ver_directive=0;
	a_bp_ver_customized=0;
	a_bp_ver_optional=0;

	a_bp_inst_state = 0;
	a_bp_inst_end_datetime = 0;
	a_bp_inst_duration=0;

	e_bp_rel=0;
	a_bp_rel_id = 0;
	a_bp_rel_name = 0;
	a_bp_rel_descr = 0;
	a_bp_rel_from = 0;
	a_bp_rel_to = 0;
	//m_status_dlg_created=false;
}
// *************************************************************************
CaplInstance *CaplBPManager::CreateBP(CaplInstance *base_bp,CaplInstance *item, const TCHAR *id, const TCHAR *name, CaplInstance *type,long creation_mode,CaplInstance **rel,CaplInstance *context,const TCHAR *descr,const TCHAR *code,const TCHAR *label,bool show_dlg)
{
	
	if(e_bp==0) return 0;

	CaplInstance *created_bp=0;
	if(!show_dlg)
	{
		if(id)
		{
			if(creation_mode!=APL_MODE_COPY_BP && m_bCheckUniqs)
			{
				//проверка уникальности id
				CaplAttrValue tst_values[2];               
				tst_values[0].value.Set((LPCTSTR)id); 
				tst_values[0].attr=a_bp_id;      
				tst_values[1].value.Set(base_bp);
				tst_values[1].attr=a_bp_parent;

				aplExtent ext_existing;
				m_data->NET_FindInstancesWithAttrValues(e_bp,2,&tst_values[0], ext_existing,false);
				if(ext_existing.GetSize())
				{
					if(m_api->m_ModeInteractive) AfxMessageBox( APL_T("Бизнес-процесс с таким обозначением уже есть в базе !!!"));
					show_dlg=true;
				}
				if(!show_dlg && code)
				{
					//проверка уникальности кода
					CaplAttrValue tst_code_values[1];					
					tst_code_values[0].value.Set((LPCTSTR)code); 
					tst_code_values[0].attr=a_bp_code;    
					ext_existing.Clear();
					m_data->NET_FindInstancesWithAttrValues(e_bp,1,&tst_code_values[0], ext_existing,false);
					if(ext_existing.GetSize())
					{
						if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Бизнес-процесс с таким кодом уже есть в базе !!!"));
						show_dlg=true;
					}
				}
			}
		}
		else
		{
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Обозначение бизнес-процесса не задано!"));
			show_dlg=true;
		}
	}
	bool add_mode=true;
	CString c_id=id;
	CString c_name=name;
	CString c_descr=descr;
	CString c_code=code;
	CString c_label=label;
	CaplInstance *c_type=type;
	bool bCustomized=false, bOptional=false;

	while(add_mode)
	{
		CBPDlg dlg;

		if(show_dlg)
		{
			if(!m_api->m_ModeInteractive)return 0;
			CaplSetResourceHandle setres(module_inst);

			dlg.m_api=m_api;
			dlg.m_data=m_data;
			dlg.m_bp_mgr=this;
			dlg.m_base_bp=base_bp; 
			dlg.m_act_id=c_id;
			dlg.m_act_name=c_name;
			dlg.m_act_descr=c_descr;
			dlg.m_act_code=c_code;
			dlg.m_act_label=c_label;
			dlg.m_type=c_type;
			dlg.m_item=item;
			dlg.m_context=context;
			dlg.m_creation_mode=creation_mode;
			dlg.DoModal();
			
			if(dlg.m_bp_ref && rel) 
				*rel=dlg.m_bp_ref;
			created_bp=dlg.m_bp;
			if(!created_bp) 
			{
				return 0;
			}
			if(m_data->IsKindOf(created_bp,e_apl_bp_ver)) 
				m_data->GetAttr(created_bp,a_bp_ver_bp,created_bp);
			add_mode=dlg.m_add_mode;
			if(add_mode)
			{
				c_id=dlg.m_act_id;
				c_name=dlg.m_act_name;
				c_descr=dlg.m_act_descr;
				c_code=dlg.m_act_code;
				c_label=dlg.m_act_label;
				c_type=dlg.m_type;
			}
		}
		else
		{
			created_bp=m_data->CreateInstance(e_bp);
			if(created_bp)
			{
				m_data->PutAttr(created_bp,a_bp_id,id);
				m_data->PutAttr(created_bp,a_bp_state,_T("working"));
				if(name) 
					m_data->PutAttr(created_bp,a_bp_name,name);
				if(descr) 
					m_data->PutAttr(created_bp,a_bp_descr,descr);
				if(code) 
					m_data->PutAttr(created_bp,a_bp_code,code);
				if(label) 
					m_data->PutAttr(created_bp,a_bp_label,label);
				if(type) 
					m_data->PutAttr(created_bp,a_bp_type,type);

				m_data->PutAttr(created_bp, a_bp_customized, bCustomized);
				m_data->PutAttr(created_bp, a_bp_optional, bOptional);

				if(item) 
				{
					CaplInstance *nRel;
					nRel=CreateAssociation(item,created_bp);
					if(nRel && context)
					{
						CaplAggr aggr;
						aggr.Add(context);
						m_data->PutAttr(nRel,a_bp_ref_frames_of_reference,aggr);
					}
					if(rel)
						*rel = nRel;
				}
			}
			add_mode=false;
		}
		if(created_bp)
		{
			CaplInstance *act=0;
			m_data->GetAttr(created_bp,a_bp_act,act);
			if(!act)
			{
				act=CreateBPVersion(created_bp,_T("0"),false);
				m_data->PutAttr(created_bp,a_bp_act,act);
				m_data->PutAttr(created_bp,a_bp_lock,act);
			}
			if(base_bp)
			{
				CaplInstance *parent_bp=base_bp;
				if(m_data->IsKindOf(base_bp,e_apl_bp_ver)) 
					m_data->GetAttr(base_bp,a_bp_ver_bp,parent_bp);
				m_data->PutAttr(created_bp,a_bp_parent,parent_bp);
				CaplAggr aggr0;
				if(m_bUseVersions)
				{
					CaplInstance *base_lock=0;
					base_lock=CheckMyLock(parent_bp,false);
					if(!base_lock) 
					{
						CheckOut(parent_bp);
						base_lock=CheckMyLock(parent_bp,true);
						if(!base_lock) 
							return 0;
					}
					m_data->GetAttr(base_lock,a_bp_ver_elements,aggr0);
					aggr0.Add(created_bp);
					m_data->PutAttr(base_lock,a_bp_ver_elements,aggr0);
				}
				else
				{
					m_data->GetAttr(base_bp,a_bp_elements,aggr0);
					aggr0.Add(created_bp);
					m_data->PutAttr(base_bp,a_bp_elements,aggr0);
				}
			}
		}
		if(NULL!=created_bp && true==m_AutoSave)
		{
			CString csAccPat;
			aplExtent aet;
			
			aet.Add(created_bp);
			if(true==show_dlg && _T("")!=dlg.m_csAccessString)
				apidata.NET_SetAccessFromPattern(&aet,dlg.m_csAccessString);
			else
				if(true==m_AutoUsurpire)
					if(TRUE==m_api->m_options_mgr.GetDefPatern(e_bp,csAccPat))
						apidata.NET_SetAccessFromPattern(&aet,csAccPat);
		}
	}
	if(m_AutoSave) 
		m_api->SaveChanges();


	return created_bp;
}

CaplInstance *CaplBPManager::CreateBPCopy(CaplInstance *base_bp,const TCHAR *id, const TCHAR *name,const TCHAR *descr,CaplInstance *item, CaplInstance *context,CaplInstance **rel,CaplInstance *parent_bp,bool recursive)
{
	if(e_bp==0) return 0;
	if(base_bp==0) return 0;
	if(base_bp==(CaplInstance*)-1) {
		if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));
		return 0;
	};
	if(base_bp->GetAccessmode()>aplRO) return 0;
	
	if(m_api->m_ModeInteractive)
	{
		if(!m_status_dlg_created && recursive)
		{
			if(!m_status_dlg.m_hWnd) m_status_dlg.Create(IDD_DISASM_STATUS);
			if(m_status_dlg.m_hWnd)
			{
				m_status_dlg_created=true;
				m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
				m_status_count=0;
				m_status_dlg.ShowWindow(SW_SHOW);
			}
		}
	}
	bool old_AutoSaveChanges=m_AutoSave;
	bool old_AutoSaveChangesChar=m_api->m_charact_mgr.m_AutoSave;
	m_AutoSave=false;
	m_api->m_charact_mgr.m_AutoSave=false;

	CString buf,buf0;
	CaplInstance *created_bp=0;
	if(!parent_bp) LoadBPInfo(base_bp,false);
	CaplInstance *base_bp_lock=CheckMyLock(base_bp,false);

	//проверяем обозначение на уникальность или формируем его при необходимости
	CaplAttrValue tst_values[2];     
	tst_values[0].attr=a_bp_id;  
	tst_values[1].attr=a_bp_parent;
	tst_values[1].value.Set(parent_bp);
	CString new_id=id;
	if(!id)
	{
		if(base_bp_lock) m_data->GetAttr(base_bp_lock,a_bp_ver_id,new_id);
		else m_data->GetAttr(base_bp,a_bp_id,new_id);
		if(m_sIdPostfixForCreateBPCopy.IsEmpty()) 	new_id+= APL_T("_копия");
		else new_id+=m_sIdPostfixForCreateBPCopy;
		tst_values[0].value.Set((LPCTSTR)new_id); 
		int copy_count=1;
		buf=new_id;
		while(!m_data->NET_TestUniqueAttrValues(e_bp,0,2,&tst_values[0], false))
		{
			buf0.Format(_T("%d"),copy_count);
			new_id=buf+buf0;
			tst_values[0].value.Set((LPCTSTR)new_id); 
			copy_count++;
		}
	}
	if(new_id==_T(""))
	{
		if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Обозначение не может быть пустым!"));
		return 0;
	}
	if(!parent_bp) ext_bps.Clear();
	//проверка уникальности id
	aplExtent ext_matched_bp;
	bool uniq=true;
	tst_values[0].value.Set((LPCTSTR)new_id); 
	if(!parent_bp) uniq=m_data->NET_TestUniqueAttrValues(e_bp,0,2,&tst_values[0], false);
	else m_data->FindInstancesWithAttrValuesInLocalCache(e_bp,0,2,&tst_values[0], ext_matched_bp,false,false,true);
	if(ext_matched_bp.GetSize() || !uniq)
	{
		if(m_api->m_ModeInteractive) AfxMessageBox( APL_T("Бизнес-процесс с таким обозначением уже есть в базе !!!"));
		return 0;
	}
	CaplInstance *type=0;
	if(base_bp_lock) m_data->GetAttr(base_bp_lock,a_bp_ver_type,type);
	else m_data->GetAttr(base_bp,a_bp_type,type);
	CString new_name=name;
	if(!name)
	{
		if(base_bp_lock) m_data->GetAttr(base_bp_lock,a_bp_ver_name,new_name);
		else m_data->GetAttr(base_bp,a_bp_name,new_name);
	}
	CString new_descr=descr;
	if(!descr)
	{
		if(base_bp_lock) m_data->GetAttr(base_bp_lock,a_bp_ver_descr,new_descr);
		else m_data->GetAttr(base_bp,a_bp_descr,new_descr);
	}

	bool old_AutoUsurpire=m_AutoUsurpire;
	m_AutoUsurpire=false;
	created_bp=CreateBP(parent_bp,item,new_id,new_name,type,APL_MODE_COPY_BP,rel,context,new_descr,0,0,false);
	if(!created_bp) return 0;
	ext_bps.Add(created_bp);

	m_data->PutAttr(created_bp,a_bp_source,base_bp);
	if(!m_sIdPostfixForCreateBPCopy.IsEmpty()) m_data->PutAttr(created_bp,a_bp_customized,true);

	CaplInstance *lock=CheckMyLock(created_bp,true);
	if(!lock) return 0;

	if(!m_sIdPostfixForCreateBPCopy.IsEmpty())  m_data->PutAttr(lock,a_bp_ver_customized,true);
		
	//копирование ресурсов
	aplExtent ext_base_res,ext_new_res;
	if(base_bp_lock) m_data->GetAttr(base_bp_lock,a_bp_ver_res,ext_base_res);
	else m_data->GetAttr(base_bp,a_bp_res,ext_base_res);
	CaplInstance *inst;
	double value;
	int i_value;
	int i;
	for(i=0;i<ext_base_res.GetSize();i++)
	{
		if(!ext_base_res[i]) continue;
		if(!ext_base_res[i]->GetType()) continue;
		if(ext_base_res[i]->GetAccessmode()>aplRO) continue;
		CaplInstance *new_res=m_data->CreateInstance(e_bp_res);
		if(new_res)
		{
			m_data->GetAttr(ext_base_res[i],a_bp_res_object,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_object,inst);
			m_data->GetAttr(ext_base_res[i],a_bp_res_unit,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_unit,inst);	
			m_data->GetAttr(ext_base_res[i],a_bp_res_derive_unit,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_derive_unit,inst);
			m_data->GetAttr(ext_base_res[i],a_bp_res_id,buf);
			if(buf!=_T("")) m_data->PutAttr(new_res,a_bp_res_id,buf);
			m_data->GetAttr(ext_base_res[i],a_bp_res_name,buf);
			if(buf!=_T("")) m_data->PutAttr(new_res,a_bp_res_name,buf);
			m_data->GetAttr(ext_base_res[i],a_bp_res_descr,buf);
			if(buf!=_T("")) m_data->PutAttr(new_res,a_bp_res_descr,buf);
			m_data->GetAttr(ext_base_res[i],a_bp_res_type,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_type,inst);
			m_data->GetAttr(ext_base_res[i],a_bp_res_val,value);
			if(value) m_data->PutAttr(new_res,a_bp_res_val,value);
			m_data->GetAttr(ext_base_res[i],a_bp_res_derive_val,value);
			if(value) m_data->PutAttr(new_res,a_bp_res_derive_val,value);
			m_data->GetAttr(ext_base_res[i],a_bp_res_assortment,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_assortment,inst);
			m_data->GetAttr(ext_base_res[i],a_bp_res_ranking,i_value);
			if(value) m_data->PutAttr(new_res,a_bp_res_ranking,i_value);
			m_data->GetAttr(ext_base_res[i],a_bp_res_ranking_rationale,buf);
			if(buf!=_T("")) m_data->PutAttr(new_res,a_bp_res_ranking_rationale,buf);
			
			m_data->PutAttr(new_res,a_bp_res_process,created_bp);
			ext_new_res.Add(new_res);
		}
	}
	if(ext_new_res.GetSize()) 
	{
		m_data->PutAttr(created_bp,a_bp_res,ext_new_res);
		m_data->PutAttr(lock,a_bp_ver_res,ext_new_res);
	}

	//копирование характеристик
	bool find_charact_in_base=false;
	if(!parent_bp) find_charact_in_base=true;
	aplExtent ext_base_char,ext_base_group,ext_new_char,ext_new_group;
	if(base_bp_lock) m_api->m_charact_mgr.FindAssociatedCharacteristic(base_bp_lock,ext_base_char,ext_base_group,false,false,find_charact_in_base);
	else m_api->m_charact_mgr.FindAssociatedCharacteristic(base_bp,ext_base_char,ext_base_group,false,false,find_charact_in_base);
	for(i=0;i<ext_base_group.GetSize();i++)//копирование групповых хар-ик
	{
		if(!ext_base_group[i]) continue;
		if(!ext_base_group[i]->GetType()) continue;
		if(ext_base_group[i]->GetAccessmode()>aplRO) continue;
		CaplInstance *new_group=0;
		m_api->m_charact_mgr.CreateCharacteristicGroup(created_bp, &new_group, ext_base_group[i],false);
		if(new_group) ext_new_group.Add(new_group);
	}
	m_data->GetAttr(lock,a_bp_ver_char_val_versions,ext_new_char);
	for(i=0;i<ext_base_char.GetSize();i++)
	{
		if(!ext_base_char[i]) continue;
		if(!ext_base_char[i]->GetType()) continue;
		if(ext_base_char[i]->GetAccessmode()>aplRO) continue;
		CaplInstance *group=0;
		CaplInstance *base_char_val=ext_base_char[i];
		if(m_data->IsKindOf(ext_base_char[i],m_api->m_charact_mgr.e_apl_charact_value_ver))
		{
			m_data->GetAttr(ext_base_char[i],m_api->m_charact_mgr.a_apl_charact_val_ver_char_value,base_char_val);
		}
		m_data->GetAttr(base_char_val,m_api->m_charact_mgr.a_apl_charact_val_group,group);
		if(group)
		{
			if(ext_base_group.Find(group)>=0) continue;//хар-ки, входящие в группы, уже скопированы
		}
		CaplInstance *new_char=0;
		if(base_bp_lock) new_char=m_api->m_charact_mgr.CopyValVersionToVal(ext_base_char[i]);
		else new_char=m_api->m_charact_mgr.CreateCopyCharacteristicVal(ext_base_char[i]);
		if(new_char) 
		{
			m_data->PutAttr(new_char,m_api->m_charact_mgr.a_apl_charact_val_item,created_bp);
			m_data->PutAttr(new_char,m_api->m_charact_mgr.a_apl_charact_val_base_item,created_bp);
			CaplInstance *char_lock=m_api->m_charact_mgr.CreateCharValVersion(new_char,_T("0"),true);
			if(char_lock) 
			{
				m_data->PutAttr(new_char,m_api->m_charact_mgr.a_apl_charact_val_lock_ver,char_lock);
				ext_new_char.Add(char_lock);
			}
		}
	}
	if(ext_new_char.GetSize()) m_data->PutAttr(lock,a_bp_ver_char_val_versions,ext_new_char);

	if(recursive && m_status_dlg_created && m_api->m_ModeInteractive)
	{
		m_status_count++;
		CString buf;buf.Format(_T("%d"),m_status_count);
		m_status_dlg.m_count.SetWindowText(buf);
	}	
	//копирование подпроцессов
	if(recursive)
	{
		aplExtent ext_sub_bp;	
		if(base_bp_lock) m_data->GetAttr(base_bp_lock,a_bp_ver_elements,ext_sub_bp);
		else m_data->GetAttr(base_bp,a_bp_elements,ext_sub_bp);
		LoadBPInfo(ext_sub_bp,false);
		m_api->m_charact_mgr.FindAssociatedCharacteristic(ext_sub_bp,ext_base_char,ext_base_group,true,true,false);
		for(int i=0;i<ext_sub_bp.GetSize();i++)
		{
			CaplInstance *subBP=ext_sub_bp[i];
			bool bSubCustomized=false;
			m_data->GetAttr(subBP, a_bp_customized, bSubCustomized);
			if(!bSubCustomized)
			{
				// Унифицированные не копируем, а заимствуем
				CaplAggr aggr0;
				m_data->GetAttr(lock,a_bp_ver_elements,aggr0);
				aggr0.Add(subBP);
				m_data->PutAttr(lock,a_bp_ver_elements,aggr0);
				continue;
			}

			CaplInstance *sub_lock=CheckMyLock(subBP,false);
			CString sub_id;
			if(sub_lock) m_data->GetAttr(sub_lock,a_bp_ver_id,sub_id);
			else m_data->GetAttr(subBP,a_bp_id,sub_id);
			CreateBPCopy(subBP,sub_id,0,0,0,0,0,created_bp,true);
		}

	}
	if(!parent_bp && m_status_dlg_created) {m_status_count=0;m_status_dlg.m_count.SetWindowText(_T(""));m_status_dlg.ShowWindow(SW_HIDE);}
	if(!parent_bp)
	{
		m_AutoSave=old_AutoSaveChanges;
		m_api->m_charact_mgr.m_AutoSave=old_AutoSaveChangesChar;

		if(m_AutoSave) m_api->SaveChanges(); 
		if(ext_bps.GetSize())
		{
			CString csAccPat;
			if(TRUE==m_api->m_options_mgr.GetDefPatern(ext_bps[0]->GetType(),csAccPat))
				apidata.NET_SetAccessFromPattern(&ext_bps,csAccPat);
		}
	}
	m_AutoUsurpire=old_AutoUsurpire;
	return created_bp;

}

CaplInstance *CaplBPManager::CreateBPInstCopy(CaplInstance *base_bp_inst,const TCHAR *id, const TCHAR *name,const TCHAR *descr,CaplInstance *bp,CaplInstance *item, CaplInstance *context,CaplInstance **rel,CaplInstance *parent_bp_inst,bool recursive)
{
	if(e_bp==0) return 0;
	if(base_bp_inst==0) return 0;
	if(base_bp_inst==(CaplInstance*)-1) {
		if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));
		return 0;
	}
	if(base_bp_inst->GetAccessmode()>aplRO) return 0;
	
	if(m_api->m_ModeInteractive)
	{
		if(!m_status_dlg_created && recursive)
		{
			if(!m_status_dlg.m_hWnd) m_status_dlg.Create(IDD_DISASM_STATUS);
			if(m_status_dlg.m_hWnd)
			{
				m_status_dlg_created=true;
				m_status_dlg.m_name.SetWindowText( APL_T("Обработано экземпляров процессов:"));
				m_status_count=0;
				m_status_dlg.ShowWindow(SW_SHOW);
			}
		}
	}
	bool old_AutoSaveChanges=m_AutoSave;
	bool old_AutoSaveChangesChar=m_api->m_charact_mgr.m_AutoSave;
	m_AutoSave=false;
	m_api->m_charact_mgr.m_AutoSave=false;

	CString buf,buf0;
	CaplInstance *created_bp_inst=0;
	if(!parent_bp_inst) LoadBPInstInfo(base_bp_inst);
	
	//проверяем обозначение на уникальность или формируем его при необходимости
	CaplAttrValue tst_values[1];     
	tst_values[0].attr=a_bp_inst_id;  

	CString new_id=id;
	if(!id)
	{
		m_data->GetAttr(base_bp_inst,a_bp_inst_id,new_id);
		new_id+= APL_T("_копия");
		tst_values[0].value.Set((LPCTSTR)new_id); 
		int copy_count=1;
		buf=new_id;
		while(!m_data->NET_TestUniqueAttrValues(e_apl_bp_inst,0,1,&tst_values[0], false))
		{
			buf0.Format(_T("%d"),copy_count);
			new_id=buf+buf0;
			tst_values[0].value.Set((LPCTSTR)new_id); 
			copy_count++;
		}
	}
	if(new_id==_T(""))
	{
		if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Обозначение не может быть пустым!"));
		return 0;
	}
	if(!parent_bp_inst) ext_bps.Clear();
	//проверка уникальности id
	aplExtent ext_matched_bp;
	tst_values[0].value.Set((LPCTSTR)new_id); 
	aplExtent ext_bp_inst;
	m_data->NET_FindInstancesWithAttrValues(e_apl_bp_inst,1,&tst_values[0],ext_bp_inst,false);
	if(ext_bp_inst.GetSize())
	{
		if(m_api->m_ModeInteractive) AfxMessageBox( APL_T("Экземпляр бизнес-процесса с таким обозначением уже есть в базе !!!"));
		return 0;
	}
	CString new_name=name;
	if(!name) m_data->GetAttr(base_bp_inst,a_bp_inst_name,new_name);
	CString new_descr=descr;
	if(!descr) m_data->GetAttr(base_bp_inst,a_bp_inst_descr,new_descr);
	if(!bp) m_data->GetAttr(base_bp_inst,a_bp_inst_process,bp);

	bool old_AutoUsurpire=m_AutoUsurpire;
	m_AutoUsurpire=false;
	created_bp_inst=CreateBPInst(parent_bp_inst,new_id,new_name,new_descr,bp,item,context,rel,false);
	if(!created_bp_inst) return 0;
	ext_bps.Add(created_bp_inst);
	m_data->GetAttr(base_bp_inst,a_bp_inst_date_time,buf);
	m_data->PutAttr(created_bp_inst,a_bp_inst_date_time,buf);

	//копирование ресурсов
	aplExtent ext_base_res,ext_new_res;
	m_data->GetAttr(base_bp_inst,a_bp_inst_res,ext_base_res);
	CaplInstance *inst;
	double value;
	int i_value;
	int i;
	for(i=0;i<ext_base_res.GetSize();i++)
	{
		if(!ext_base_res[i]) continue;
		if(!ext_base_res[i]->GetType()) continue;
		if(ext_base_res[i]->GetAccessmode()>aplRO) continue;
		CaplInstance *new_res=m_data->CreateInstance(e_bp_res);
		if(new_res)
		{
			m_data->GetAttr(ext_base_res[i],a_bp_res_object,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_object,inst);
			m_data->GetAttr(ext_base_res[i],a_bp_res_unit,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_unit,inst);	
			m_data->GetAttr(ext_base_res[i],a_bp_res_derive_unit,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_derive_unit,inst);
			m_data->GetAttr(ext_base_res[i],a_bp_res_id,buf);
			if(buf!=_T("")) m_data->PutAttr(new_res,a_bp_res_id,buf);
			m_data->GetAttr(ext_base_res[i],a_bp_res_name,buf);
			if(buf!=_T("")) m_data->PutAttr(new_res,a_bp_res_name,buf);
			m_data->GetAttr(ext_base_res[i],a_bp_res_descr,buf);
			if(buf!=_T("")) m_data->PutAttr(new_res,a_bp_res_descr,buf);
			m_data->GetAttr(ext_base_res[i],a_bp_res_type,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_type,inst);
			m_data->GetAttr(ext_base_res[i],a_bp_res_val,value);
			if(value) m_data->PutAttr(new_res,a_bp_res_val,value);
			m_data->GetAttr(ext_base_res[i],a_bp_res_derive_val,value);
			if(value) m_data->PutAttr(new_res,a_bp_res_derive_val,value);
			m_data->GetAttr(ext_base_res[i],a_bp_res_assortment,inst);
			if(inst) m_data->PutAttr(new_res,a_bp_res_assortment,inst);
			m_data->GetAttr(ext_base_res[i],a_bp_res_ranking,i_value);
			if(value) m_data->PutAttr(new_res,a_bp_res_ranking,i_value);
			m_data->GetAttr(ext_base_res[i],a_bp_res_ranking_rationale,buf);
			if(buf!=_T("")) m_data->PutAttr(new_res,a_bp_res_ranking_rationale,buf);
			
			m_data->PutAttr(new_res,a_bp_res_process,created_bp_inst);
			ext_new_res.Add(new_res);
		}
	}
	if(ext_new_res.GetSize()) 
	{
		m_data->PutAttr(created_bp_inst,a_bp_inst_res,ext_new_res);
	}

	//копирование характеристик
	bool find_charact_in_base=false;
	if(!parent_bp_inst) find_charact_in_base=true;
	aplExtent ext_base_char,ext_base_group,ext_new_char,ext_new_group;
	m_api->m_charact_mgr.FindAssociatedCharacteristic(base_bp_inst,ext_base_char,ext_base_group,false,false,find_charact_in_base);
	for(i=0;i<ext_base_group.GetSize();i++)//копирование групповых хар-ик
	{
		if(!ext_base_group[i]) continue;
		if(!ext_base_group[i]->GetType()) continue;
		if(ext_base_group[i]->GetAccessmode()>aplRO) continue;
		CaplInstance *new_group=0;
		m_api->m_charact_mgr.CreateCharacteristicGroup(created_bp_inst, &new_group, ext_base_group[i],false);
		if(new_group) ext_new_group.Add(new_group);
	}
	for(i=0;i<ext_base_char.GetSize();i++)
	{
		if(!ext_base_char[i]) continue;
		if(!ext_base_char[i]->GetType()) continue;
		if(ext_base_char[i]->GetAccessmode()>aplRO) continue;
		CaplInstance *group=0;
		m_data->GetAttr(ext_base_char[i],m_api->m_charact_mgr.a_apl_charact_val_group,group);
		if(group)
		{
			if(ext_base_group.Find(group)>=0) continue;//хар-ки, входящие в группы, уже скопированы
		}
		CaplInstance *new_char=0;
		new_char=m_api->m_charact_mgr.CreateCopyCharacteristicVal(ext_base_char[i]);
		if(new_char) 
		{
			m_data->PutAttr(new_char,m_api->m_charact_mgr.a_apl_charact_val_item,created_bp_inst);
			m_data->PutAttr(new_char,m_api->m_charact_mgr.a_apl_charact_val_base_item,created_bp_inst);
			CaplInstance *char_lock=m_api->m_charact_mgr.CreateCharValVersion(new_char,_T("0"),true);
			if(char_lock) m_data->PutAttr(new_char,m_api->m_charact_mgr.a_apl_charact_val_lock_ver,char_lock);
		}
	}
	

	if(recursive && m_status_dlg_created && m_api->m_ModeInteractive)
	{
		m_status_count++;
		CString buf;buf.Format(_T("%d"),m_status_count);
		m_status_dlg.m_count.SetWindowText(buf);
	}	
	//копирование подпроцессов
	if(recursive)
	{
		aplExtent ext_sub_bp;	
		m_data->GetAttr(base_bp_inst,a_bp_inst_elements,ext_sub_bp);
		LoadBPInstInfo(ext_sub_bp);
		m_api->m_charact_mgr.FindAssociatedCharacteristic(ext_sub_bp,ext_base_char,ext_base_group,true,true,false);
		for(int i=0;i<ext_sub_bp.GetSize();i++)
		{
			CString base_id,sub_id;
			CreateBPInstCopy(ext_sub_bp[i],0,0,0,0,0,0,0,created_bp_inst,true);
		}

	}
	if(!parent_bp_inst && m_status_dlg_created) {m_status_count=0;m_status_dlg.m_count.SetWindowText(_T(""));m_status_dlg.ShowWindow(SW_HIDE);}
	if(!parent_bp_inst)
	{
		m_AutoSave=old_AutoSaveChanges;
		m_api->m_charact_mgr.m_AutoSave=old_AutoSaveChangesChar;

		if(m_AutoSave) m_api->SaveChanges(); 
		if(ext_bps.GetSize()>0 && true==m_AutoUsurpire)
		{
			CString csAccPat;
			if(TRUE==m_api->m_options_mgr.GetDefPatern(ext_bps[0]->GetType(),csAccPat))
				apidata.NET_SetAccessFromPattern(&ext_bps,csAccPat);
		}
	}
	m_AutoUsurpire=old_AutoUsurpire;
	return created_bp_inst;

}


CaplInstance* CaplBPManager::CreateBPRelation(CaplInstance* BpFrom, CaplInstance* BpTo, bool bTestUnique, TCHAR* id, TCHAR* name, TCHAR* descr)
{
	if(BpFrom==NULL || BpTo==NULL) return NULL;

	if(bTestUnique)
	{
		CaplAttrValue tst_val[2];
		tst_val[0].attr = a_bp_rel_from;
		tst_val[1].attr = a_bp_rel_to;
		tst_val[0].value.Set(BpFrom);
		tst_val[1].value.Set(BpTo);
		aplExtent ext;
		m_data->NET_FindInstancesWithAttrValues(e_bp_rel, 2, &tst_val[0], ext, false);
		if(ext.Size>0)
			return ext[0];
	}
	CaplInstance* nRel = m_data->CreateInstance(e_bp_rel);
	m_data->PutAttr(nRel, a_bp_rel_from, BpFrom);
	m_data->PutAttr(nRel, a_bp_rel_to, BpTo);
	m_data->PutAttr(nRel, a_bp_rel_id, id);
	m_data->PutAttr(nRel, a_bp_rel_name, name);
	m_data->PutAttr(nRel, a_bp_rel_descr, descr);
	if(m_AutoSave)
		m_api->SaveChanges();

	return nRel;
}

bool CaplBPManager::FindBpFrom(CaplInstance* Bp, aplExtent &ext, aplExtent* rel)
{
	ext.Clear();
	if(rel)
		rel->Clear();
	if(Bp==NULL) return false;
	aplExtent rels;
	CaplInstance* BpFrom, *BpTo;
	int i;
	if(m_api->m_data.IsConnected() && Bp->GetId()!=0)
	{
		CaplLoadData ld(m_data, DEF_SOURCE);
		ld.AddQuery(_T('b'), Bp->GetId(), e_bp_rel, a_bp_rel_to, true, true);
		ld.LoadEx();
	}
	m_api->m_data.GetEntityExtent(e_bp_rel, rels);
	for(i=0; i<rels.GetSize(); i++)
	{
		if(!rels[i]) continue;
		if(rels[i]->GetAccessmode()>aplRO) continue;
		m_data->GetAttr(rels[i], a_bp_rel_to, BpTo);
		if(BpTo!=Bp) continue;
		m_data->GetAttr(rels[i], a_bp_rel_from, BpFrom);
		if(BpFrom && BpFrom->GetAccessmode()<=aplRO)
		{
			ext.Add(BpFrom);
			if(rel)
				rel->Add(rels[i]);
		}
	}
	return true;
}

bool CaplBPManager::FindBpTo(CaplInstance* Bp, aplExtent &ext, aplExtent* rel)
{
	ext.Clear();
	if(rel)
		rel->Clear();
	if(Bp==NULL) return false;

	aplExtent rels, res;
	CaplInstance* BpFrom, *BpTo;
	int i;
	if(m_api->m_data.IsConnected() && Bp->GetId()!=0)
	{
		CaplLoadData ld(m_data, DEF_SOURCE);
		ld.AddQuery(_T('b'), Bp->GetId(), e_bp_rel, a_bp_rel_from, true, true);
		ld.LoadEx();
	}
	m_api->m_data.GetEntityExtent(e_bp_rel, rels);
	for(i=0; i<rels.GetSize(); i++)
	{
		if(!rels[i]) continue;
		if(rels[i]->GetAccessmode()>aplRO) continue;

		m_data->GetAttr(rels[i], a_bp_rel_from, BpFrom);
		if(BpFrom!=Bp) continue;
		
		m_data->GetAttr(rels[i], a_bp_rel_to, BpTo);
		if(BpTo && BpTo->GetAccessmode()<=aplRO)
		{
			ext.Add(BpTo);
			if(rel)
				rel->Add(rels[i]);
		}
	}

	return true;
}

CaplInstance *CaplBPManager::CreateBPInst(CaplInstance *base_bp_inst,const TCHAR *id,const TCHAR *name,const TCHAR *descr,CaplInstance *bp,CaplInstance *item,CaplInstance *context,CaplInstance **rel,bool show_dlg)
{
	CaplInstance *created_bp_inst=0;
	
	if(!show_dlg)
	{
		if(id)
		{
			//проверка уникальности id
			CaplAttrValue tst_values[1];               
			tst_values[0].value.Set((LPCTSTR)id); 
			tst_values[0].attr=a_bp_inst_id;      
			aplExtent ext_bp_inst;
			m_data->NET_FindInstancesWithAttrValues(e_apl_bp_inst,1,&tst_values[0],ext_bp_inst,false);
			if(ext_bp_inst.GetSize())
			{
				if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Экземпляр бизнес-процесса с таким обозначением уже есть в базе !!!"));
				show_dlg=true;
			}
		}
		else
		{
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Обозначение экземпляра бизнес-процесса не задано!"));
			show_dlg=true;
		}
	}
	bool add_mode=true;
	CString c_id=id;
	CString c_name=name;
	CString c_descr=descr;
	CaplInstance *c_bp=bp;

	if(rel!=0)*rel=0;

	while(add_mode)
	{
		CBPInstDlg dlg;
		if(show_dlg)
		{
			if(!m_api->m_ModeInteractive)return 0;
			CaplSetResourceHandle setres(module_inst);

			dlg.m_api=m_api;
			dlg.m_id=c_id;
			dlg.m_name=c_name;
			dlg.m_descr=c_descr;
			dlg.m_bp=c_bp;
			dlg.m_base_bp_inst=base_bp_inst;
			dlg.m_item=item;
			dlg.m_context=context;
			dlg.DoModal();
			created_bp_inst=dlg.m_inst;
			if(!created_bp_inst) 
			{
				return 0;
			}
			if(dlg.m_bp_inst_ref && rel) 
				*rel = dlg.m_bp_inst_ref;

			add_mode=dlg.m_add_mode;
			if(add_mode)
			{
				c_id=dlg.m_id;
				c_name=dlg.m_name;
				c_descr=dlg.m_descr;
				c_bp=dlg.m_bp;
			}
		}
		else
		{
			created_bp_inst=m_data->CreateInstance(e_apl_bp_inst);
			if(created_bp_inst)
			{
				m_data->PutAttr(created_bp_inst,a_bp_inst_id,id);
				CString curdate;
				aplDate2String(COleDateTime::GetCurrentTime(), curdate);
				m_data->PutAttr(created_bp_inst,a_bp_inst_date_time,curdate);
				if(name) 
					m_data->PutAttr(created_bp_inst,a_bp_inst_name,name);
				if(descr) 
					m_data->PutAttr(created_bp_inst,a_bp_inst_descr,descr);
				m_data->PutAttr(created_bp_inst, a_bp_inst_process, c_bp);
				CaplInstance* relat = 0;
				if(item) 
					relat=CreateInstanceAssociation(item,created_bp_inst,context);
				if(rel!=0) 
					*rel = relat;
			}
			add_mode=false;
		}
		if(created_bp_inst)
		{
			if(base_bp_inst)
			{
				CaplAggr aggr0;
				m_data->GetAttr(base_bp_inst,a_bp_inst_elements,aggr0);
				aggr0.Add(created_bp_inst);
				m_data->PutAttr(base_bp_inst,a_bp_inst_elements,aggr0);
			}
		}
		
		if(NULL!=created_bp_inst && true==m_AutoSave)
		{
			CString csAccPat;
			aplExtent aet;

			m_api->SaveChanges();
			
			aet.Add(created_bp_inst);
			if(true==show_dlg && _T("")!=dlg.m_csAccessString)
				apidata.NET_SetAccessFromPattern(&aet,dlg.m_csAccessString);
			else
				if(true==m_AutoUsurpire)
					if(TRUE==m_api->m_options_mgr.GetDefPatern(e_apl_bp_inst,csAccPat))
						apidata.NET_SetAccessFromPattern(&aet,csAccPat);
		}
	}

	if(m_AutoSave) 
		m_api->SaveChanges();


	return created_bp_inst;
}
//*************************************************************
CaplInstance *CaplBPManager::CreateBPResource(CaplInstance *inst,CaplInstance *base_res_or_pdr,CaplInstance *object,const TCHAR *id, const TCHAR *name,const TCHAR *descr, CaplInstance *type,bool show_dlg)
{
	if(inst==0) return 0;
	if(inst==(CaplInstance*)-1) {
		if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));
		return 0;
	};
	if(inst->GetAccessmode()>aplRW){
		if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),inst);
		return 0;
	}
	CaplInstance *lock=0;
	CaplInstance *bp=0;
	CaplInstance *bp_inst=0;
	if(m_data->IsKindOf(inst,e_bp)) bp=inst;
	else if(m_data->IsKindOf(inst,e_apl_bp_inst)) bp_inst=inst;
	else return 0;

	if(m_bUseVersions && bp)
	{
		if(!CheckMyLockAndCheckOut(bp))
			return 0;
		lock=CheckMyLock(bp,true);
		if(!lock) return 0;
	}

	CaplAggr aggr;
	if(lock) m_data->GetAttr(lock,a_bp_ver_res,aggr);
	else if(bp) m_data->GetAttr(bp,a_bp_res,aggr);
	else if(bp_inst) m_data->GetAttr(bp_inst,a_bp_inst_res,aggr);
	if(object || base_res_or_pdr)
	{
		CaplInstance *base_obj=0;
		if(base_res_or_pdr)
			if(base_res_or_pdr->GetAccessmode()<aplNO)
				if(m_data->IsKindOf(base_res_or_pdr,e_bp_res))
					m_data->GetAttr(base_res_or_pdr,a_bp_res_object,base_obj);
		for(int i=0;i<aggr.GetSize();i++)
		{
			CaplInstance *res=0,*res_obj=0;
			aggr.GetByIndex(i,res);
			if(!res) continue;if(res->GetAccessmode()>aplRO) continue;
			m_data->GetAttr(res,a_bp_res_object,res_obj);
			if(res_obj==object || res_obj==base_obj) 
			{
				if(m_api->m_ModeInteractive)
				{
					if(IDYES!=AfxMessageBox( APL_T("Такой ресурс уже существует! Добавить?"),MB_YESNO|MB_ICONWARNING)) return 0;
					break;
				}
			}
		}
	}
	CaplInstance *new_res=0;
	if((object || base_res_or_pdr) && !show_dlg)
	{
		new_res=m_data->CreateInstance(e_bp_res);
		if(object) m_data->PutAttr(new_res,m_api->m_bp_mgr.a_bp_res_object,object);
		if(id)     m_data->PutAttr(new_res,a_bp_res_id,id);
		if(name)   m_data->PutAttr(new_res,a_bp_res_name,name);
		if(descr)  m_data->PutAttr(new_res,a_bp_res_descr,descr);
		if(type)   m_data->PutAttr(new_res,a_bp_res_type,type);
		if(bp) m_data->PutAttr(new_res,a_bp_res_process,bp);
		else if(bp_inst) m_data->PutAttr(new_res,a_bp_res_process,bp_inst);
	}
	else
	{
		CaplSetResourceHandle setres(module_inst);
		CBPResDlg dlg;
		dlg.m_api=m_api;
		if(bp) dlg.m_bp=bp;
		if(bp_inst) dlg.m_bp=bp_inst;
		if(base_res_or_pdr)
		{
			if(base_res_or_pdr->GetAccessmode()<aplNO)
			{
				if(m_data->IsKindOf(base_res_or_pdr,e_bp_res))
					dlg.m_base_res=base_res_or_pdr;		
				else if(m_data->IsKindOf(base_res_or_pdr,m_api->m_prd_mgr.e_pdr))
					dlg.m_base_pdr=base_res_or_pdr;		
			}
		}
		dlg.m_obj=object;
		dlg.m_id=id;
		dlg.m_name=name;
		dlg.m_descr=descr;
		dlg.m_type=type;
		if(dlg.DoModal()==IDOK)
		{
			/* Проверка есть внутри диалога
			bool res_exist=false;
			
			for(int i=0;i<aggr.GetSize();i++)
			{
				CaplInstance *res=0,*res_obj=0;
				aggr.GetByIndex(i,res);
				if(!res) continue;if(res->GetAccessmode()>aplRO) continue;
				m_data->GetAttr(res,a_bp_res_object,res_obj);
				if(res_obj==dlg.m_obj) 
				{
					if(m_api->m_ModeInteractive)
					{
						if(IDYES!=AfxMessageBox( APL_T("Такой ресурс уже существует! Продолжить?"),MB_YESNO|MB_ICONWARNING))
						{
							res_exist=true;
							break;
						}
					}
				}
			}
			if(!res_exist)*/
			{
				new_res=m_data->CreateInstance(e_bp_res);
				m_data->PutAttr(new_res,a_bp_res_object,dlg.m_obj);
				m_data->PutAttr(new_res,a_bp_res_unit,dlg.m_unit);	
				m_data->PutAttr(new_res,a_bp_res_derive_unit,dlg.m_unit_der);
				m_data->PutAttr(new_res,a_bp_res_id,dlg.m_id);
				m_data->PutAttr(new_res,a_bp_res_name,dlg.m_name);
			    m_data->PutAttr(new_res,a_bp_res_descr,dlg.m_descr);
				m_data->PutAttr(new_res,a_bp_res_type,dlg.m_type);
				m_data->PutAttr(new_res,a_bp_res_val,dlg.m_res_value);
				m_data->PutAttr(new_res,a_bp_res_derive_val,dlg.m_res_der_value);
				m_data->PutAttr(new_res,a_bp_res_assortment,dlg.m_assortment);
				m_data->PutAttr(new_res,a_bp_res_ranking,dlg.m_ranking_value);
				m_data->PutAttr(new_res,a_bp_res_ranking_rationale,dlg.m_ranking_rationale);
			}
		}
	}
	if(new_res)
	{
		if(bp) m_data->PutAttr(new_res,a_bp_res_process,bp);
		else if(bp_inst) m_data->PutAttr(new_res,a_bp_res_process,bp_inst);
		aggr.Add(new_res);
		if(lock) m_data->PutAttr(lock,a_bp_ver_res,aggr);
		else if(bp) m_data->PutAttr(bp,a_bp_res,aggr);
		else if(bp_inst) m_data->PutAttr(bp_inst,a_bp_inst_res,aggr);

	}
	if(m_AutoSave) 
		m_api->SaveChanges();

	if(true==m_AutoUsurpire)
	{
		CaplEntity*	et	=NULL;
		aplExtent	aet;
		CString		csAccPat;

		et=e_bp_res;

		if(NULL!=new_res)
			if(aplOWN==new_res->GetAccessmode())
				aet.Add(new_res);
		if(TRUE==m_api->m_options_mgr.GetDefPatern(et,csAccPat))
			apidata.NET_SetAccessFromPattern(&aet,csAccPat);
	}

	return new_res;
}

bool CaplBPManager::LoadBPInfo(CaplInstance *bp,bool bLoadSubBpInfo)
{	
	if(bp==0)		return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetId()==0)	return true;
	if(bp->GetType()==0)	return false;
	if (m_data==0)	return false;

	aplExtent ext; ext.Unique=false;
	ext.Add(bp);
	return LoadBPInfo(ext,bLoadSubBpInfo);
}
//*************************************************************
bool CaplBPManager::LoadBPInfo(aplExtent  &ext,bool bLoadSubBpInfo,bool show_status_dlg)
{
	if(e_bp==0)		return false;
	if(m_data==0)	return  false;
	if(ext.Size<1) return true;
	
	int i,n=0,z=0;
	int iLoadBPNum=-1;
	int iLoadBPVerNum=-1;
	aplExtent ext_bp,ext_bp_ver;
	CaplLoadData ld(m_data,DEF_SOURCE);

	CaplSetResourceHandle setres(module_inst);

	CDisAsmStatusDlg* dlg=0;
	if(show_status_dlg && m_api->m_data.m_IsWaitDlg) 
	{
		dlg= new CDisAsmStatusDlg;
		dlg->Create(IDD_DISASM_STATUS);
		dlg->m_name.SetWindowText( APL_T("Загружено атрибутов:"));
		dlg->ShowWindow(SW_SHOW);
	}
	CString buf;
	int all_l_count=0;

	int l_count=0;
	for(i=0;i<ext.GetSize();i++)
	{
		if(m_bContinue)
		{
			if(*m_bContinue==false) break;
		}
		CaplInstance *bp=ext[i];
		// DIV: переделал на серию else if. Если оставить конструкции типа if(prd==0) continue; - то при последнем инстансе в экстенте ==0 запрос для первых выполнен не будет
		if(bp==0) {;}
		else if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;}
		else if(bp->GetId()==0){;}
		else if(bp->GetType()==0){;}
		else if(bp->GetAccessmode()>aplRO){;}
		else if(m_data->IsKindOf(bp, e_bp))
		{
			if(iLoadBPNum==-1){iLoadBPNum=ld.AddQuery(-1,bp, true);}
			else{ld.AddQuery(iLoadBPNum, bp, true);}
			l_count++;
		}
		else if(m_data->IsKindOf(bp, e_apl_bp_ver))
		{
			if(iLoadBPVerNum==-1){iLoadBPVerNum=ld.AddQuery(-1,bp, true);}
			else{ld.AddQuery(iLoadBPVerNum, bp, true);}
			l_count++;
		}
		if((l_count==m_MaxItemsLoad || i==ext.GetSize()-1) && (iLoadBPNum!=-1 || iLoadBPVerNum!=-1))
		{
			if(iLoadBPNum!=-1)
			{
				n=ld.AddQuery(_T('d'), iLoadBPNum, 0,a_bp_lock, true,true);
				  ld.AddQuery(n,_T('d'), iLoadBPNum, 0,a_bp_act, true,true);
				  ld.AddQuery(_T('d'), iLoadBPNum, 0,a_bp_res, true,true);
				  ld.AddQuery(_T('d'), iLoadBPNum, 0, a_bp_type, true, true);
				  ld.AddQuery(_T('d'), iLoadBPNum, 0, a_bp_class, true, true);
				if(bLoadSubBpInfo)
				  ld.AddQuery(_T('d'), iLoadBPNum, 0,a_bp_elements, true,true);
				if(m_bUseVersions)
				{	
					  ld.AddQuery(_T('d'), n, 0,a_bp_ver_base, true,true);
					  ld.AddQuery(_T('d'), n, 0,a_bp_ver_author, true,true);
					  ld.AddQuery(_T('d'), n, 0,a_bp_ver_res, true,true);
				      if(bLoadSubBpInfo)
						ld.AddQuery(_T('d'), n, 0,a_bp_ver_elements, true,true);
				}
			}
			if(iLoadBPVerNum!=-1)
			{
				  ld.AddQuery(_T('d'), iLoadBPVerNum, 0,a_bp_ver_bp, true,true);
				  ld.AddQuery(_T('d'), iLoadBPVerNum, 0,a_bp_ver_author, true,true);
				  ld.AddQuery(_T('d'), iLoadBPVerNum, 0,a_bp_ver_res, true,true);
				  ld.AddQuery(_T('d'), iLoadBPVerNum, 0,a_bp_ver_class, true,true);
				  if(bLoadSubBpInfo)
					ld.AddQuery(_T('d'), iLoadBPVerNum, 0,a_bp_ver_elements, true,true);
			}
			all_l_count+=l_count;

			ld.LoadEx();
			ld.ClearQuery();

			if(dlg)
			{
				buf.Format(_T("%d"),int(((double)all_l_count/(double)ext.Size)*100));
				buf+=_T("%");
				dlg->m_count.SetWindowText(buf);	
			}
			l_count=0;
			iLoadBPNum=-1;
			iLoadBPVerNum=-1;
		}
	}

	if(dlg)
	{
		dlg->ShowWindow(SW_HIDE);
		dlg->DestroyWindow();
		delete dlg;
	}

	return true;
}


bool CaplBPManager::ShowBPProperties(CaplInstance *bp,CaplInstance *bp_ref,bool *is_ok)
{
	if(e_bp==0) return false;
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;

	CaplSetResourceHandle setres(module_inst);

	CBPDlg dlg;

	m_data->ClearLastQuery();
	LoadBPInfo(bp);
	CaplInstance *ver=0,*lock=0,*bp_ver_bp=0,*base_bp=0;

	if(m_data->IsKindOf(bp,e_bp))
	{
		if(m_bUseVersions)
		{
			lock=CheckMyLock(bp,false);
			ver=lock;
		}
	}
	else if(m_data->IsKindOf(bp,e_apl_bp_ver))
		ver=bp;

	if(ver) 
	{
	    m_data->GetAttr(ver,a_bp_ver_bp,bp_ver_bp);
		if(bp_ver_bp) 
			if(bp_ver_bp->GetAccessmode()<aplNO)
				m_data->GetAttr(bp_ver_bp,a_bp_lock,lock);

		dlg.m_bp=ver;
		if(bp->GetAccessmode()>aplRW || lock!=ver)
			dlg.m_ReadOnly=true;
	}
	else
	{
		dlg.m_bp=bp;
		if(m_bUseVersions)
			dlg.m_ReadOnly=true;
	}

	dlg.m_api=m_api;
	dlg.m_data=m_data;
	dlg.m_bp_mgr=this;
	dlg.m_bp_ref=bp_ref;
	if(is_ok!=0){*is_ok=false;}

	if(dlg.DoModal()==IDOK) 
	{
		if(is_ok!=0){*is_ok=true;}
		if(m_AutoSave) 
			m_api->SaveChanges();

		if(dlg.m_bp->GetAccessmode()==aplOWN)
		{
			aplExtent aet;
			aet.Add(dlg.m_bp);
			apidata.NET_SetAccessFromPattern(&aet,dlg.m_csAccessString);
		}
	}
	return true;
}

bool CaplBPManager::ShowBPInstProperties(CaplInstance *bp_inst,CaplInstance *bp_inst_ref)
{
	if(bp_inst==0) return false;
	if(bp_inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp_inst->GetType()==0) return false;
	if(bp_inst->GetAccessmode()>aplRO)
	{
		if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp_inst);
		return false;
	}
	
	CaplSetResourceHandle setres(module_inst);

	CBPInstDlg dlg;

	m_data->ClearLastQuery();
	LoadBPInstInfo(bp_inst);

	if(bp_inst->GetAccessmode()==aplRO) dlg.m_ReadOnly=true;
	dlg.m_inst=bp_inst;
	dlg.m_api=m_api;
	dlg.m_bp_inst_ref=bp_inst_ref;

	dlg.DoModal();
	if(m_AutoSave) 
		m_api->SaveChanges();
	if(dlg.m_inst->GetAccessmode()==aplOWN)
	{
		aplExtent aet;
		aet.Add(dlg.m_inst);
		apidata.NET_SetAccessFromPattern(&aet,dlg.m_csAccessString);
	}
	return true;
}

bool CaplBPManager::ShowBPResourceProperties(CaplInstance *res,CaplInstance **new_res,CaplInstance *bp_rev)
{
	if(res==0) return false;
	if(res==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(res->GetAccessmode()>aplRO)
	{
		if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),res);
		return false;
	}
	CaplInstance *process=0;
	m_data->GetAttr(res,a_bp_res_process,process);
	if(!process) return false;
	if(!new_res) return false;
	*new_res=0;
	CaplSetResourceHandle setres(module_inst);
	CBPResDlg dlg;
	dlg.m_inst=res;
	dlg.m_api=m_api;
	dlg.m_bp=process;
	if(m_bUseVersions)
	{
		if(res->GetAccessmode()>aplRW) 
			dlg.m_ReadOnly=true;
		if(bp_rev)
		{
			dlg.m_bp_rev=bp_rev;
			dlg.m_ReadOnly=true;
		}
		else
		{
			if(m_data->IsKindOf(process,e_bp))
			{
				CaplInstance *lock=CheckMyLock(process,false);
				if(!lock) dlg.m_ReadOnly=true;
			}
		}
	}
	bool changed_smth=false;
	if(dlg.DoModal()==IDOK)
	{ 
		m_api->SaveChanges();
		*new_res=dlg.m_inst;
		changed_smth=true;
	}
	return changed_smth;
}
//*************************************************************
bool CaplBPManager::DeleteBP(CaplInstance *bp, bool delete_sub_bp, CaplInstance *deleted_parent)
{
	if(m_api==0) return false;
	if(e_bp==0) return false;
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	LoadBPInfo(bp);
	if(bp->GetType()==0) return false;
	if(bp->GetAccessmode()>aplOWN) return false;
	CaplInstance *inst;
	CaplAggr aggr0;
	int i;

	aplExtent ext;
	CaplAttrValue tst_value;

	if(m_data->IsKindOf(bp,e_bp))
	{
		tst_value.value.Set(bp);
		tst_value.attr=a_bp_elements;
		m_data->NET_FindInstancesWithAttrValues(e_bp,1,&tst_value,ext,false);
		if(ext.Size>0)
		{
			bool b_del=false;
			if(ext.Size==1)
			{
				if(ext[0]==deleted_parent) b_del=true;
			}
			if(b_del==false){ if(deleted_parent!=0) return false;}
		}
		
		// проверяем на использование бп в каком-либо изменении
		aplExtent ext_changes;
		CaplAttrValue find_val[1];
		find_val[0].attr = m_api->m_change_mgr.a_abpc_bp;
		find_val[0].value.Set(bp);
		
		apidata.NET_FindInstancesWithAttrValues(m_api->m_change_mgr.e_abpc, 1, &find_val[0], ext_changes, false);
		
		if (ext_changes.GetSize())
		{
			int res = IDYES;
			if(m_api->m_ModeInteractive)
				res = AfxMessageBox( APL_T("Бизнесс-процесс используется в изменении. Всё равно удалить?"), MB_YESNO | MB_ICONQUESTION);

			if (res == IDYES)
			{
				for (int i = 0; i < ext_changes.GetSize(); i++)
				{
					aplExtent aggr;
					
					apidata.GetAttr(ext_changes[i], m_api->m_change_mgr.a_chng_item_attachment, aggr);
					for (int l = 0; l < aggr.GetSize(); l++)
					{
						apidata.NET_DeleteBlob(aggr[l], m_api->m_doc_mgr.a_apl_stored_document_source);
						apidata.DeleteInstance(aggr[i]);
					}
					
					apidata.DeleteInstance(ext_changes[i]);
				}
			}
			else
				return false;
		}

		//Удаление версий бп
		if(m_bUseVersions) 
		{
			aplExtent ext0;
			CaplAggr aggr;
			GetAllBPVersion(bp,ext0);
			for(int i=0;i<ext0.GetSize();i++)
			{
				if(ext0[i]->GetAccessmode()>aplOWN) continue;
				// удаляем статусы и характеристики объекта
				m_api->m_appr_mgr.DeleteAllApproval(ext0[i]);
				m_api->m_charact_mgr.DeleteAllAssociatedCharacteristic(ext0[i]);

				m_data->DeleteInstance(ext0[i]);		
			}

			CaplInstance *act=ext[0];
	
		}
		if(delete_sub_bp)
		{
			m_data->GetAttr(bp,a_bp_elements,aggr0);	
			for(int i=0;i<aggr0.GetSize();i++)
			{
				aggr0.GetByIndex(i,inst);
				if(inst!=0) DeleteBP(inst,true,bp);
			}
		}

		// Удаление ассоциаторов
		CaplAttrValue tst_values[1];
		tst_values[0].value.Set(bp);
		tst_values[0].attr=a_bp_ref_process;
		m_data->NET_FindInstancesWithAttrValues(e_bp_ref,1,&tst_values[0],ext,true);
		for(i=0;i<ext.Size;i++)
		{
			if(!ext[i]) continue;if(ext[i]->GetAccessmode()>aplOWN) continue;
			m_data->DeleteInstance(ext[i]);
		}
		//удаление характеристик
//		ext.Clear();
//		tst_values[0].attr=m_api->m_charact_mgr.a_apl_charact_val_item;
//		m_data->NET_FindInstancesWithAttrValues(m_api->m_charact_mgr.e_apl_charact_value,1,&tst_values[0],ext,true);
//		for(i=0;i<ext.Size;i++)
//		{
//			if(!ext[i]) continue;if(ext[i]->GetAccessmode()>aplOWN) continue;
//			m_api->m_charact_mgr.DeleteCharacteristic(ext[i]);//чтобы убить и версии характеристик
//		}
		// удаляем статусы и характеристики объекта
		m_api->m_appr_mgr.DeleteAllApproval(bp);
		m_api->m_charact_mgr.DeleteAllAssociatedCharacteristic(bp);

		//удаление ресурсов
		ext.Clear();
		tst_values[0].attr=a_bp_res_process;
		m_data->NET_FindInstancesWithAttrValues(e_bp_res,1,&tst_values[0],ext,true);
		for (i = 0; i < ext.Size; i++)
		{
			if(!ext[i]) continue;if(ext[i]->GetAccessmode()>aplOWN) continue;
			m_data->DeleteInstance(ext[i]);
		}
		//удалим ассоциации со справочником

		m_api->m_classifier_mgr.DeleteClassifierAssociation(bp,0);

		bool bIsAdmin = m_data->IsAdmin();
		CaplInstance *iParent = NULL, *iBP = bp;
		CaplInstance *ref_item = NULL;
			
		if(bIsAdmin)
		{
			// для изменения в дальнейшем характеристики "Расцеховка"

			CaplInstance *iParent = NULL, *iBP = bp;
			// выделяем родительский бизнес-процесс
			do 
			{
				m_api->m_data.GetAttr(iBP, m_api->m_bp_mgr.a_bp_parent, iParent);
				if(iParent != NULL)
					iBP = iParent;
			}
			while(iParent != NULL);
			
			// ищем pdf 
			CaplAttrValue attr;
			aplExtent ref_ext;
			attr.attr = m_api->m_bp_mgr.a_bp_ref_process;
			attr.value.Set(iBP);
			m_api->m_data.NET_FindInstancesWithAttrValues(m_api->m_bp_mgr.e_bp_ref, 1, &attr, ref_ext, false);
			if(ref_ext.GetSize() > 0)
				m_api->m_data.GetAttr(ref_ext[0], m_api->m_bp_mgr.a_bp_ref_item, ref_item);	
		}
		
		m_data->DeleteInstance(bp);
		
		if(bIsAdmin)
			RebuildCharactRasc(ref_item);				
	}
	else if(m_data->IsKindOf(bp,e_apl_bp_ver))
	{
		CaplInstance *bp_ver_bp=0;
		m_data->GetAttr(bp,a_bp_ver_bp,bp_ver_bp);	
		CaplInstance *act=0;
		if(bp_ver_bp)
		{
			if(bp_ver_bp->GetAccessmode()<aplNO)
			{
				m_data->GetAttr(bp_ver_bp,a_bp_act,act);
				if(act==bp) 
				{
					if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Нельзя удалять активную версию!"));
					return false;
				}
			
			}
		}
		// удаляем статусы и характеристики объекта
		m_api->m_appr_mgr.DeleteAllApproval(bp);
		m_api->m_charact_mgr.DeleteAllAssociatedCharacteristic(bp);
		m_data->DeleteInstance(bp);
	}
	
	if(m_AutoSave)
	{
		if(deleted_parent==0) m_api->SaveChanges();
	}
	
	return true;
}

//*************************************************************
bool CaplBPManager::DeleteBPInst(CaplInstance *bp_inst, bool delete_sub_bp_inst, CaplInstance *deleted_parent)
{
	if(m_api==0) return false;
	if(bp_inst==0) return false;
	if(bp_inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp_inst->GetType()==0) return false;
	if(bp_inst->GetAccessmode()>aplOWN) return false;
	LoadBPInstInfo(bp_inst);

	CaplInstance *inst;
	CaplAggr aggr0;
	aplExtent ext;
	CaplAttrValue tst_value;

	tst_value.value.Set(bp_inst);
	tst_value.attr=a_bp_inst_elements;
	m_data->NET_FindInstancesWithAttrValues(e_apl_bp_inst,1,&tst_value,ext,false);
	if(ext.Size>0)
	{
		bool b_del=false;
		if(ext.Size==1)
		{
			if(ext[0]==deleted_parent) b_del=true;
		}
		if(b_del==false){ if(deleted_parent!=0) return false;}
	}
	if(delete_sub_bp_inst)
	{
		m_data->GetAttr(bp_inst,a_bp_inst_elements,aggr0);	
		for(int i=0;i<aggr0.GetSize();i++)
		{
			aggr0.GetByIndex(i,inst);
			if(inst!=0) DeleteBPInst(inst,true,bp_inst);
		}
	}
	// Удаление ассоциаторов
	CaplAttrValue tst_values[1];
	tst_values[0].value.Set(bp_inst);
	tst_values[0].attr=a_bp_inst_ref_process;
	m_data->NET_FindInstancesWithAttrValues(e_bp_inst_ref,1,&tst_values[0],ext,true);
	for(int i=0;i<ext.Size;i++)
	{
		if(!ext[i]) continue;if(ext[i]->GetAccessmode()>aplOWN) continue;
		m_data->DeleteInstance(ext[i]);
	}
	//удаление характеристик
//	ext.Clear();
//	tst_values[0].attr=m_api->m_charact_mgr.a_apl_charact_val_item;
//	m_data->NET_FindInstancesWithAttrValues(m_api->m_charact_mgr.e_apl_charact_value,1,&tst_values[0],ext,true);
//	for(i=0;i<ext.Size;i++)
//	{
//		if(!ext[i]) continue;if(ext[i]->GetAccessmode()>aplOWN) continue;
//		m_api->m_charact_mgr.DeleteCharacteristic(ext[i]);//чтобы убить и версии характеристик
//	}
	// удаляем статусы и характеристики объекта
	m_api->m_appr_mgr.DeleteAllApproval(bp_inst);
	m_api->m_charact_mgr.DeleteAllAssociatedCharacteristic(bp_inst);


	//удалим ассоциации со справочником
	m_api->m_classifier_mgr.DeleteClassifierAssociation(bp_inst,0);
	
	m_data->DeleteInstance(bp_inst);
	
	if(m_AutoSave)
	{
		if(deleted_parent==0) m_api->SaveChanges();
	}

	return true;
}
//*************************************************************
CaplInstance *CaplBPManager::FindBPById(const TCHAR *id, bool bAutoLoadInfo)
{
	if (id==0)return 0;
	if (m_data==0)return 0;
	if(e_bp==0) return 0;

	aplExtent ext;
	CaplAttrValue tst_value;

	tst_value.value.Set(id);
	tst_value.attr=a_bp_id;
	m_data->NET_FindInstancesWithAttrValues(e_bp,1,&tst_value,ext,false);
	if(ext.Size==0) return NULL;
	
	if(bAutoLoadInfo)
		LoadBPInfo(ext);

	return ext[0];
}
//*************************************************************
bool CaplBPManager::WhereUsedBP(aplExtent &items, aplExtent &ext, aplExtent *refs, bool bReferenceOnly)
{
	ext.Clear();

	if(m_api==NULL) return false;
	if(!m_api->m_data.IsDictLoad()) return false;

	aplExtent tmp_refs;
	int i,j,k;
	if(m_data->IsConnected())
	{
		// чтение из базы
		CaplLoadData ld(m_data,DEF_SOURCE);
		for(i=0; i<items.GetSize(); i++)
		{
			if(items[i]==NULL) continue;
			if(items[i]->GetAccessmode()>aplRO) continue;
			if(items[i]->GetId()==0) continue;
			if(items[i]->GetType()==NULL) continue;

			ld.AddQuery(0, items[i]);
		}
		if(ld.IsQueryNotEmpty())
		{
			ld.AddQuery(_T('r'), 0, e_bp_ref, a_bp_ref_process, true, true);
			if (!ld.LoadEx())
			{
				if(m_data->GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS)
				{
					if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
				}
			}
		}
		ld.ClearQuery();
		if(!bReferenceOnly)
		{
			for(i=0; i<items.GetSize(); i++)
			{
				if(items[i]==NULL) continue;
				if(items[i]->GetAccessmode()>aplRO) continue;
				if(items[i]->GetId()==0) continue;
				if(items[i]->GetType()==NULL) continue;
				
				ld.AddQuery(0, items[i]);
			}
			if(ld.IsQueryNotEmpty())
			{
				j=	ld.AddQuery(_T('r'), 0, e_bp, a_bp_elements, true);
				ld.AddQuery(_T('d'), j, 0,a_bp_elements, true);
				if (!ld.LoadEx())
				{
					if(m_data->GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS){
						if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
					}
				}
			}

			if(m_bUseVersions)
			{
				ld.ClearQuery();
				
				for(i=0; i<items.GetSize(); i++)
				{
					if(items[i]==NULL) continue;
					if(items[i]->GetAccessmode()>aplRO) continue;
					if(items[i]->GetId()==0) continue;
					if(items[i]->GetType()==NULL) continue;
					
					ld.AddQuery(0, items[i]);
				}
				
				if(ld.IsQueryNotEmpty())
				{
					j=	ld.AddQuery(_T('r'), 0, e_apl_bp_ver, a_bp_ver_elements, true);
					k=	ld.AddQuery(_T('d'), j, 0,a_bp_ver_bp, true);
					ld.AddQuery(_T('d'), k, 0,a_bp_lock, true);
					ld.AddQuery(_T('d'), j, 0,a_bp_ver_author, true);
					ld.AddQuery(_T('d'), j, 0,a_bp_ver_elements, true);
					ld.LoadEx();
				}
			}
		}
	}

	CaplInstance *item;
	CaplInstance *process;
	aplExtent references;
	m_api->m_data.GetEntityExtent(e_bp_ref, references);
	for(i=0; i<references.Size; i++)
	{
		m_api->m_data.GetAttr(references[i], a_bp_ref_process, process);
		if(items.Find(process)>-1)
		{
			tmp_refs.Add(references[i]);
			m_api->m_data.GetAttr(references[i], a_bp_ref_item, item);
			ext.Add(item);
		}
	}

	if(!bReferenceOnly)
	{
		aplExtent ext1;
		CaplAggr aggr0;
		CaplInstance *inst;
		m_data->GetEntityExtent(e_bp,ext1);
		
		for(i=0;i<ext1.Size;i++)
		{
			if(ext1[i]->GetAccessmode()>aplRO) continue;
			m_data->GetAttr(ext1[i],a_bp_elements,aggr0);	
			for(j=0;j<aggr0.GetSize();j++)
			{
				aggr0.GetByIndex(j,inst);
				if(items.Find(inst)>-1) 
				{
					ext.Add(ext1[i]);
					break;
				}
			}
		}
		if(m_bUseVersions)
		{
			ext1.Clear();
			aggr0.Clear();
			m_data->GetEntityExtent(e_apl_bp_ver,ext1);
			for(i=0;i<ext1.Size;i++)
			{
				if(ext1[i]->GetAccessmode()>aplRO) continue;
				m_data->GetAttr(ext1[i],a_bp_ver_elements,aggr0);	
				CaplInstance *inst0=0;
				m_data->GetAttr(ext1[i],a_bp_ver_bp,inst0);	
				for(j=0;j<aggr0.GetSize();j++)
				{
					aggr0.GetByIndex(j,inst);
					if(!inst) continue;
					if(inst->GetAccessmode()>aplRO) continue;
					if(!inst0) continue;
					if(inst0->GetAccessmode()>aplRO) continue;
					if(items.Find(inst)>-1) 
					{
						CaplInstance *lock=CheckMyLock(inst0,false);
						if(lock==ext1[i]) {ext.Add(inst0);break;}
					}
				}
			}
		}
	}
	

	if(m_api->m_data.IsConnected())
		LoadExtentInfo(ext);	

	return true;
}

bool CaplBPManager::WhereUsedBP(CaplInstance *bp, aplExtent &ext, aplExtent *refs, bool bReferenceOnly)
{
	aplExtent items;
	items.Add(bp);

	return WhereUsedBP(items, ext, refs, bReferenceOnly);
}

bool CaplBPManager::WhereUsedBPInst(aplExtent &bp_insts, aplExtent &ext, aplExtent &refs, bool bFromBase)
{
	ext.Clear();
	
	if(m_api==NULL) return false;
	if(!m_api->m_data.IsDictLoad()) return false;
	if(bp_insts.GetSize()==0) return true;
	
	if(bFromBase && m_api->m_data.IsConnected())
	{
		int j, i;
		int ld_ind2;
		int cnt, count;
		int block_size;
		CaplLoadData ld(m_data,DEF_SOURCE);
		block_size = m_MaxItemsLoad*1.5>bp_insts.GetSize()?bp_insts.GetSize():m_MaxItemsLoad;
		block_size = block_size>0?block_size:500;
		cnt = bp_insts.GetSize()/block_size+1;
		for(i=0; i<cnt; i++)
		{
			count = (i+1)*block_size<bp_insts.GetSize() ? block_size : bp_insts.GetSize()-(i*block_size);
			for(j=0; j<count; j++)
			{
				if(bp_insts[i*block_size+j]==NULL) continue;
				if(bp_insts[i*block_size+j]->GetId()==0) continue;
				if(bp_insts[i*block_size+j]->GetType()==NULL) continue;
				ld.AddQuery(0, bp_insts[i*block_size+j]);
			}
			if(ld.IsQueryNotEmpty())
			{
				ld_ind2 =	ld.AddQuery(_T('r'), 0, e_bp_inst_ref, a_bp_inst_ref_process, true, true);
							ld.AddQuery(_T('d'), ld_ind2, 0,a_bp_inst_ref_process, true);
							ld.AddQuery(_T('d'), ld_ind2, 0,a_bp_inst_ref_item, true);
				
				if (!ld.LoadEx())
				{
					if(m_data->GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS){
						if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
					}
				}
			}
			ld.ClearQuery();
		}
	}
	
	int i;
	aplExtent refs_ext;
	CaplInstance* process;
	CaplInstance* item;
	
	m_api->m_data.GetEntityExtent(e_bp_inst_ref, refs_ext);
	for(i=0; i<refs_ext.GetSize(); i++)
	{
		m_api->m_data.GetAttr(refs_ext[i], a_bp_inst_ref_process, process);
		if(bp_insts.Find(process)>-1)
		{
			m_api->m_data.GetAttr(refs_ext[i], a_bp_inst_ref_item, item);
			ext.Add(item);
			refs.Add(refs_ext[i]);
		}
	}
	if(bFromBase)
		m_api->LoadExtentInfo(ext);	

	return true;
}

bool CaplBPManager::WhereUsedBPInst(aplExtent &bp_insts, aplExtent &ext, bool bFromBase, bool bReferenceOnly)
{
	ext.Clear();

	if(m_api==NULL) return false;
	if(!m_api->m_data.IsDictLoad()) return false;
	if(bp_insts.GetSize()==0) return true;

	if(bFromBase && m_api->m_data.IsConnected())
	{
		int j, i;
		int ld_ind1, ld_ind2;
		int cnt, count;
		int block_size;
		bool bLoad = false;
		CaplLoadData ld(m_data,DEF_SOURCE);
		block_size = m_MaxItemsLoad*1.5>bp_insts.GetSize()?bp_insts.GetSize():m_MaxItemsLoad;
		block_size = block_size>0?block_size:500;
		cnt = bp_insts.GetSize()/block_size+1;
		for(i=0; i<cnt; i++)
		{
			count = (i+1)*block_size<bp_insts.GetSize() ? block_size : bp_insts.GetSize()-(i*block_size);
			for(j=0; j<count; j++)
			{
				if (bp_insts[i * block_size + j] == NULL) continue;
				if (bp_insts[i * block_size + j]->GetId() == 0) continue;
				if (bp_insts[i * block_size + j]->GetType() == NULL) continue;

				ld.AddQuery(0, bp_insts[i * block_size + j]);
			}
			if(ld.IsQueryNotEmpty())
			{
				if(!bReferenceOnly)
				{
					ld_ind1 =	ld.AddQuery(_T('r'), 0, e_apl_bp_inst, a_bp_inst_elements, true);
					ld.AddQuery(_T('d'), ld_ind1, 0,a_bp_inst_elements, true);
				}
				ld_ind2 =	ld.AddQuery(_T('r'), 0, e_bp_inst_ref, a_bp_inst_ref_process, true, true);
				//ld.AddQuery(_T('d'), ld_ind2, 0,a_bp_inst_ref_process, true); - запросы получает атрибуты, уже запрошенные предыдущим. Ибо у предыдущего два труя на конце...
				//ld.AddQuery(_T('d'), ld_ind2, 0,a_bp_inst_ref_item, true);
				
				if (!ld.LoadEx())
				{
					if(m_data->GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS){
						if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
					}
				}
			}
			ld.ClearQuery();
		}
	}

	int i, j;
	aplExtent tmp;
	aplExtent insts_ext;
	aplExtent refs_ext;
	CaplInstance* process;
	CaplInstance* item;

	if(!bReferenceOnly)
	{
		m_api->m_data.GetEntityExtent(e_apl_bp_inst, insts_ext);
		for(i=0; i<insts_ext.GetSize(); i++)
		{
			m_api->m_data.GetAttr(insts_ext[i], a_bp_inst_elements, tmp);
			if(tmp.GetSize()<bp_insts.GetSize())
			{
				for(j=0; j<tmp.GetSize(); j++)
				{
					if(bp_insts.Find(tmp[j])>-1)
						ext.Add(insts_ext[i]);
				}
			}
			else
			{
				for(j=0; j<bp_insts.GetSize(); j++)
				{
					if(tmp.Find(bp_insts[j])>-1)
						ext.Add(insts_ext[i]);
				}
			}
		}
	}
	m_api->m_data.GetEntityExtent(e_bp_inst_ref, refs_ext);
	for(i=0; i<refs_ext.GetSize(); i++)
	{
		m_api->m_data.GetAttr(refs_ext[i], a_bp_inst_ref_process, process);
		if(bp_insts.Find(process)>-1)
		{
			m_api->m_data.GetAttr(refs_ext[i], a_bp_inst_ref_item, item);
			ext.Add(item);
		}
	}
	if(bFromBase)
	{
		m_api->LoadExtentInfo(ext);	
	}
	return true;
}
//*************************************************************
bool CaplBPManager::WhereUsedBPInst(CaplInstance *bp_inst, aplExtent &ext, bool bFromBase, bool bReferenceOnly)
{
	aplExtent BpInsts;
	BpInsts.Add(bp_inst);
	return WhereUsedBPInst(BpInsts, ext, bFromBase, bReferenceOnly);
}
//*************************************************************
bool CaplBPManager::ItemWhereUsedAsResource(CaplInstance *item,aplExtent &ext_bp,aplExtent &ext_bp_inst)
{
	if(item==0) return false;
	if(item==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(item->GetType()==0) return false;
	if(item->GetAccessmode()>aplRO) return false;

	int i,j;
	if(item->GetId()!=0 && m_api->m_data.IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		i=ld.AddQuery(_T('b'), item->GetId(), e_bp_res,a_bp_res_object, true);
		ld.AddQuery(_T('d'), i, 0,a_bp_res_object, true);
		j=ld.AddQuery(_T('d'), i, 0,a_bp_res_process, true);
		ld.AddQuery(_T('d'), j, 0,a_bp_res, true);
		ld.AddQuery(_T('d'), j, 0,a_bp_inst_res, true);
		if (!ld.LoadEx())
		{
			if(m_data->GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS){
				if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
			}
		}
	}

	aplExtent ext;
	m_data->GetEntityExtent(e_bp_res,ext);
	for(i=0;i<ext.Size;i++)
	{
		CaplInstance *inst=0;
		m_data->GetAttr(ext[i],a_bp_res_object,inst);
		if(inst==item)
		{
			CaplAggr aggr;
			CaplInstance *process=0,*inst2=0;
			m_data->GetAttr(ext[i],a_bp_res_process,process);
			if(!process) continue;
			if(m_data->IsKindOf(process,e_bp))
			{
				CaplInstance *lock=CheckMyLock(process,false);
				if(lock) m_data->GetAttr(lock,a_bp_ver_res,aggr);
				else m_data->GetAttr(process,a_bp_res,aggr);
				bool found=false;
				for(j=0;j<aggr.GetSize();j++)
				{
					aggr.GetByIndex(j,inst2);
					if(inst2==ext[i]) {found=true;break;}
				}
				if(found) ext_bp.Add(process);
			}
			else if(m_data->IsKindOf(process,e_apl_bp_inst))
			{
				m_data->GetAttr(process,a_bp_inst_res,aggr);
				bool found=false;
				for(j=0;j<aggr.GetSize();j++)
				{
					aggr.GetByIndex(j,inst2);
					if(inst2==ext[i]) {found=true;break;}
				}
				if(found) ext_bp_inst.Add(process);
			}
		}
	}
	return true;
}

bool CaplBPManager::LoadDictionary()
{
	if(m_data==0) return false;
	if(!m_data->IsConnected()) return true;
	CaplLoadData ld(m_data,DEF_SOURCE);
	int i=ld.AddQuery(_T('e'), 0, e_bp_res_type,0, true);
	ld.AddQuery(_T('d'), i, 0, a_bp_res_type_name, true);
	i=ld.AddQuery(_T('e'), 0, e_bp_type,0, true);
	ld.AddQuery(_T('d'), i, 0, a_bp_type_name, true);
	ld.LoadEx(true,0, APL_T("Чтение типов бизнес-процессов"));
	return true;
}
//*************************************************************
bool CaplBPManager::LoadBPResourcesInfo(CaplInstance *res)
{
	if(res==0)		return false;
	if(res==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(res->GetId()==0)	return true;
	if(res->GetType()==0)	return false;
	if (m_data==0)	return false;

	aplExtent ext; ext.Unique=false;
	ext.Add(res);
	return LoadBPResourcesInfo(ext);
}

bool CaplBPManager::LoadBPResourcesInfo(aplExtent &ext)
{
	if(m_data==0)	return  false;
	if(ext.Size<1) return true;
	
	int i,j;
	int iLoad=0;
	if(!m_data->IsConnected()) 
	{
		CaplLoadData ld(m_data,DEF_SOURCE);

		for(i=0;i<ext.Size;i++)
		{
			CaplInstance *res=ext[i];
			if(res==0) continue;
			if(res->GetId()==0) continue;
			if(res->GetType()==0) continue;
			iLoad++;
			ld.AddQuery(0,res,true);
			if(iLoad==m_MaxItemsLoad || (i==(ext.Size-1) && iLoad>0))
			{
				iLoad=0;
				j=ld.AddQuery(_T('d'), 0, 0, a_bp_res_object, true);
				
				ld.AddQuery(_T('d'), j, 0, m_api->m_prd_inst_mgr.a_lot_id, true);
				ld.AddQuery(_T('d'), j, 0, m_api->m_prd_inst_mgr.a_lot_pdf,true);
				j=ld.AddQuery(_T('d'), j, 0, m_api->m_prd_inst_mgr.a_lot_size, true);
				ld.AddQuery(_T('d'), j, 0, m_api->m_prd_inst_mgr.a_mwu_val, true);
				ld.AddQuery(_T('d'), j, 0, m_api->m_prd_inst_mgr.a_mwu_unit, true);
				if(!ld.LoadEx()){
					if(apidata.GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS){
						if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
					}
				}
			}
		}
	}

	aplExtent ext_res_obj;
	CaplInstance *inst=0;
	for(i=0;i<ext.GetSize();i++)
	{
		inst=0;
		m_data->GetAttr(ext[i],a_bp_res_object,inst);
		if(!inst) continue;
		if(inst->GetType()==0) continue;
		ext_res_obj.Add(inst);
	}
	LoadExtentInfo(ext_res_obj);

	return true;
}

bool CaplBPManager::LoadAllBPResources(CaplInstance *bp, aplExtent &ext)
{
	ext.Clear();
	if(m_data==0) return false;
	if(!m_data->IsConnected()) return true;
	if(m_api==0) return false;
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(bp->GetAccessmode()>aplRO) return false;
	if(e_bp==0) return false;

	int i,j,k;
	CaplInstance *inst;

	if(bp->GetId()!=0)
	{
		// Чтение из базы
		if(m_data->IsConnected())
		{
			if(m_data->IsKindOf(bp,e_apl_bp_ver) || m_data->IsKindOf(bp,e_bp))
				LoadBPInfo(bp,false);
			else if(m_data->IsKindOf(bp,e_apl_bp_inst))
				LoadBPInstInfo(bp);

			CaplLoadData ld(m_data,DEF_SOURCE);
			CaplAggr aggr;
			if(m_data->IsKindOf(bp,e_bp))
			{
				if(m_bUseVersions)
				{
					CaplInstance *lock=CheckMyLock(bp,false);
					if(lock)
						m_data->GetAttr(lock,a_bp_ver_res,aggr);
					else
						m_data->GetAttr(bp,a_bp_res,aggr);
				}
				else
					m_data->GetAttr(bp,a_bp_res,aggr);
			}
			else if(m_data->IsKindOf(bp,e_apl_bp_ver))
				m_data->GetAttr(bp,a_bp_ver_res,aggr);
			else if(m_data->IsKindOf(bp,e_apl_bp_inst))
				m_data->GetAttr(bp,a_bp_inst_res,aggr);

			if(aggr.GetSize()>0)
			{
				for(int i=0;i<aggr.GetSize();i++)
				{
					inst=0;
					aggr.GetByIndex(i,inst);
					if(!inst) continue;
					if(inst->GetAccessmode()>aplRO) continue;
					if(inst->GetType()==0) continue;
					ext.Add(inst);
					ld.AddQuery(0,inst,true);
				}
				if(ld.IsQueryNotEmpty())
				{
					j=ld.AddQuery(_T('d'), 0, 0, a_bp_res_object, true);
					ld.AddQuery(_T('d'), j, 0, m_api->m_prd_inst_mgr.a_lot_id, true);
					ld.AddQuery(_T('d'), j, 0, m_api->m_prd_inst_mgr.a_lot_pdf,true);
					k=ld.AddQuery(_T('d'), j, 0, m_api->m_prd_inst_mgr.a_lot_size, true);
					ld.AddQuery(_T('d'), k, 0, m_api->m_prd_inst_mgr.a_mwu_val, true);
					ld.AddQuery(_T('d'), k, 0, m_api->m_prd_inst_mgr.a_mwu_unit, true);

					ld.LoadEx();
				}
			}
		}
	}
	
	aplExtent ext_res_obj;
	for(i=0;i<ext.GetSize();i++)
	{
		inst=0;
		m_data->GetAttr(ext[i],a_bp_res_object,inst);
		if(!inst) continue;
		if(inst->GetType()==0) continue;
		ext_res_obj.Add(inst);
	}
	LoadExtentInfo(ext_res_obj);
	
	return true;
}


//*************************************************************
bool CaplBPManager::FindAssociatedBP(aplExtent &ext, aplExtent &out_ext, aplExtent &out_rel,CaplInstance *context,bool b_loadInfo,bool show_status_dlg) 
{
	out_ext.Clear();
	out_rel.Clear();
	if(m_data==0) return false;
	if(e_bp==0) return false;
	if(ext.GetSize()==0)return true;
	int i;
	if(m_data->IsConnected())
	{
		CaplSetResourceHandle setres(module_inst);

		CDisAsmStatusDlg* dlg=0;
		if(show_status_dlg && m_api->m_data.m_IsWaitDlg) 
		{
			dlg= new CDisAsmStatusDlg;
			dlg->Create(IDD_DISASM_STATUS);
			dlg->m_name.SetWindowText( APL_T("Обработано:"));
			dlg->ShowWindow(SW_SHOW);
		}
		CString buf;

		CaplLoadData ld(m_data,DEF_SOURCE);
		int l_count=0;
		int all_l_count=0;
		for(i=0;i<ext.GetSize();i++)
		{
			if(m_bContinue)
			{
				if(*m_bContinue==false) break;
			}
			if(ext[i]) 
				if(ext[i]->GetId()) 
					if(ext[i]->GetAccessmode()<aplNO) 
					{
						l_count++;
						ld.AddQuery(0,ext[i]);
					}
			if((l_count==m_MaxItemsLoad || i==ext.GetSize()-1) && ld.IsQueryNotEmpty())
			{
				ld.AddQuery(_T('r'), 0, e_bp_ref,a_bp_ref_item, true,true);
				ld.LoadEx();
				ld.ClearQuery();
				all_l_count+=l_count;
				if(dlg)
				{
					buf.Format(_T("%d"),int(((double)all_l_count/(double)ext.Size)*100));
					buf+=_T("%");
					dlg->m_count.SetWindowText(buf);	
				}
				l_count=0;
			}
		}
		if(dlg)
		{
			dlg->ShowWindow(SW_HIDE);
			dlg->DestroyWindow();
			delete dlg;
		}
	}
	if(m_bContinue)
	{
		if(*m_bContinue==false) return false;
	}

	aplExtent ext_items,ext_act_ref;
	ext_items.Append(ext);
	CSortClass::SortExtentByInst(ext_items);
	CaplInstance *inst0;
	int item_num;
	m_data->GetEntityExtent(e_bp_ref,ext_act_ref);
	for(i=0;i<ext_act_ref.Size;i++)
	{
		if(m_bContinue)
		{
			if(*m_bContinue==false) break;
		}
		m_data->GetAttr(ext_act_ref[i],a_bp_ref_item,inst0);
		item_num=aplQFindInstInExtent(ext_items,inst0);
		if(item_num>-1)
		{
			bool bAdd=true;
			if(context!=0)
				if(!IsItemInContext(ext_act_ref[i],context,a_bp_ref_frames_of_reference)) bAdd=false;
			m_data->GetAttr(ext_act_ref[i],a_bp_ref_process,inst0);
			if(inst0!=0 && bAdd)
			{
				if(inst0->GetType()!=0)
				{
					if(inst0->GetAccessmode()<=aplRO)
					{
						out_rel.Add(ext_act_ref[i]);
						out_ext.Add(inst0);
					}
				}
			}
		}
	}
	if(m_bContinue)
	{
		if(*m_bContinue==false) return false;
	}
	if(out_ext.GetSize() && b_loadInfo) LoadBPInfo(out_ext,false,show_status_dlg);

	return true;
}
//*************************************************************
bool CaplBPManager::FindAssociatedBP(CaplInstance *inst, aplExtent &out_ext, aplExtent &out_rel,CaplInstance *context,bool from_base) 
{
	out_ext.Clear();
	out_rel.Clear();
	if(m_data==0) return false;
	if(inst==0) return false;
	if(inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(inst->GetType()==0) return false;
	if(inst->GetAccessmode()>aplRO) return false;
	if(e_bp==0) return false;

	int i;
	if(inst->GetId()!=0 && from_base)
	{
		// Чтение из базы
		if(m_data->IsConnected())
		{
			CaplLoadData ld(m_data,DEF_SOURCE);
			// ссылка
			i=ld.AddQuery(_T('b'), inst->GetId(), e_bp_ref,a_bp_ref_item, true,true);
			ld.LoadEx();
		}
	}
	aplExtent ext_act_ref;
	CaplInstance *inst0;
	CaplAggr aggr;
	m_data->GetEntityExtent(e_bp_ref,ext_act_ref);
	for(i=0;i<ext_act_ref.Size;i++)
	{
		m_data->GetAttr(ext_act_ref[i],a_bp_ref_item,inst0);
		if(inst==inst0)
		{
			bool bAdd=true;
			if(context!=0)
				if(!IsItemInContext(ext_act_ref[i],context,a_bp_ref_frames_of_reference)) bAdd=false;
			m_data->GetAttr(ext_act_ref[i],a_bp_ref_process,inst0);
			if(inst0!=0 && bAdd)
			{
				if(inst0->GetType()!=0)
				{
					if(inst0->GetAccessmode()<=aplRO)
					{
						out_rel.Add(ext_act_ref[i]);
						out_ext.Add(inst0);
					}
				}
			}
		}
	}
	if(out_ext.GetSize() && from_base && m_api->m_data.IsConnected()) 
		LoadBPInfo(out_ext);

	return true;
}
//*************************************************************
bool CaplBPManager::FindAssociatedBPInst(CaplInstance *inst, aplExtent &out_ext, aplExtent &out_rel,CaplInstance *context,bool from_base) 
{
	out_ext.Clear();
	out_rel.Clear();
	if(m_data==0) return false;
	if(inst==0) return false;
	if(inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(inst->GetType()==0) return false;
	if(inst->GetAccessmode()>aplRO) return false;

	int i;
	if(inst->GetId()!=0 && from_base)
	{
		// Чтение из базы
		if(m_data->IsConnected())
		{
			CaplLoadData ld(m_data,DEF_SOURCE);
			// ссылка
			i=ld.AddQuery(_T('b'), inst->GetId(), e_bp_inst_ref,a_bp_inst_ref_item, true,true);
			ld.LoadEx();
		}
	}
	aplExtent ext_act_ref;
	CaplInstance *inst0;
	CaplAggr aggr;
	m_data->GetEntityExtent(e_bp_inst_ref,ext_act_ref);
	for(i=0;i<ext_act_ref.Size;i++)
	{
		m_data->GetAttr(ext_act_ref[i],a_bp_inst_ref_item,inst0);
		if(inst==inst0)
		{
			bool bAdd=true;
			if(context!=0)
				if(!IsItemInContext(ext_act_ref[i],context,a_bp_inst_ref_frames_of_reference)) bAdd=false;
			m_data->GetAttr(ext_act_ref[i],a_bp_inst_ref_process,inst0);
			if(inst0!=0 && bAdd)
			{
				if(inst0->GetType()!=0)
				{
					if(inst0->GetAccessmode()<=aplRO)
					{
						out_rel.Add(ext_act_ref[i]);
						out_ext.Add(inst0);
					}
				}
			}
		}
	}
	if(out_ext.GetSize() && from_base) LoadBPInstInfo(out_ext);

	return true;
}

bool CaplBPManager::FindAssociatedBPInst(aplExtent &ext, aplExtent &out_ext, aplExtent &out_rel,CaplInstance *context) 
{
	out_ext.Clear();
	out_rel.Clear();
	if(m_data==0) return false;
	if(ext.GetSize()==0) return false;
	CaplInstance* inst;
	ext.Sort();
	
	int i;
	// Чтение из базы
	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		for(i=0;i<ext.GetSize();i++){
			inst=ext.GetAt(i);
			if(inst->GetType()==0) return false;
			if(inst->GetAccessmode()>aplRO) return false;
			if(inst->GetId()!=0)
			{
				// ссылка
				ld.AddQuery(0,inst);
			}
		}
		if(ld.IsQueryNotEmpty())
		{
			i=ld.AddQuery(_T('r'), 0, e_bp_inst_ref,a_bp_inst_ref_item, true,true);
			ld.LoadEx();
		}
	}
	aplExtent ext_act_ref;
	CaplInstance *inst0;
	CaplAggr aggr;
	m_data->GetEntityExtent(e_bp_inst_ref,ext_act_ref);
	for(i=0;i<ext_act_ref.Size;i++)
	{
		m_data->GetAttr(ext_act_ref[i],a_bp_inst_ref_item,inst0);
		
		if(aplQFindInstInExtent(ext,inst0)!=-1)
		{
			bool bAdd=true;
			if(context!=0)
				if(!IsItemInContext(ext_act_ref[i],context,a_bp_inst_ref_frames_of_reference)) bAdd=false;

			m_data->GetAttr(ext_act_ref[i],a_bp_inst_ref_process,inst0);
			if(inst0!=0 && bAdd)
			{
				if(inst0->GetType()!=0)
				{
					if(inst0->GetAccessmode()<=aplRO)
					{
						out_rel.Add(ext_act_ref[i]);
						out_ext.Add(inst0);
					}
				}
			}
		}
	}
	if(out_ext.GetSize()) LoadBPInstInfo(out_ext);
	
	return true;
}


//*************************************************************
CaplInstance *CaplBPManager::CreateAssociation(CaplInstance *inst,CaplInstance *bp, const TCHAR *id,CaplInstance *zagotov)
{
	if(m_data==0) return 0;
	if(inst==0) return 0;
	if(inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(inst->GetType()==0) return 0;
	if(inst->GetAccessmode()>aplRO){if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),inst);return 0;}
	if(bp==0) return 0;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(bp->GetType()==0) return 0;
	if(bp->GetAccessmode()>aplRO){if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp);return 0;}
	if(e_bp==0) return 0;

	CaplInstance *rel=FindAssociation(inst,bp);

	if(rel!=0) return rel;
	
	rel=m_data->CreateInstance(e_bp_ref);
	m_data->PutAttr(rel,a_bp_ref_process,bp);
	m_data->PutAttr(rel,a_bp_ref_item,inst);
	if(m_AutoSave) m_api->SaveChanges();
	return rel;
}
//*************************************************************
CaplInstance *CaplBPManager::CreateInstanceAssociation(CaplInstance *item,CaplInstance *bp_inst,CaplInstance *context,const TCHAR *id, bool bTestUnique)
{
	if(m_data==0) return 0;
	if(item==0) return 0;
	if(item==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(item->GetType()==0) return 0;
	if(item->GetAccessmode()>aplRO){if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),item);return 0;}
	if(bp_inst==0) return 0;
	if(bp_inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(bp_inst->GetType()==0) return 0;
	if(bp_inst->GetAccessmode()>aplRO) return 0;

	CaplInstance *rel;
	if(bTestUnique)
	{
		rel=FindInstanceAssociation(item,bp_inst);
		if(rel!=0) return rel;
	}
	
	rel=m_data->CreateInstance(e_bp_inst_ref);
	m_data->PutAttr(rel,a_bp_inst_ref_process,bp_inst);
	m_data->PutAttr(rel,a_bp_inst_ref_item,item);
	if(id) m_data->PutAttr(rel,a_bp_inst_ref_id,id);
	if(context)
	{
		CaplAggr aggr;
		aggr.Add(context);
		m_data->PutAttr(rel,a_bp_inst_ref_frames_of_reference,aggr);
	}
	if(m_AutoSave) m_api->SaveChanges();
	return rel;
}
//*************************************************************
CaplInstance *CaplBPManager::FindAssociation(CaplInstance *inst,CaplInstance *bp)
{
	if(m_data==0) return 0;
	if(inst==0) return 0;
	if(inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(inst->GetType()==0) return 0;
	if(bp==0) return 0;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(bp->GetType()==0) return 0;
	if(e_bp==0) return 0;

	CaplAttrValue tst_values[2];
	aplExtent ext;

	tst_values[0].value.Set(inst);
	tst_values[0].attr=a_bp_ref_item;

	tst_values[1].value.Set(bp);
	tst_values[1].attr=a_bp_ref_process;

	m_data->NET_FindInstancesWithAttrValues(e_bp_ref,2,&tst_values[0],ext,true);

	if(ext.Size==0) return 0;
	CaplInstance *rel=ext[0];
	if(rel->GetId()==0) return rel;

	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		int i=ld.AddQuery(-1,rel,true);
		ld.AddQuery(_T('d'), i, 0,a_bp_ref_item, true, true);
		ld.AddQuery(_T('d'), i, 0,a_bp_ref_process, true, true);
		ld.AddQuery(_T('d'), i, 0,a_bp_ref_zagotov, true, true);
		ld.LoadEx();
	}
	return rel;
}
//*************************************************************
CaplInstance *CaplBPManager::FindInstanceAssociation(CaplInstance *item,CaplInstance *bp_inst)
{
	if(m_data==0) return 0;
	if(item==0) return 0;
	if(item==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(item->GetType()==0) return 0;
	if(bp_inst==0) return 0;
	if(bp_inst==(CaplInstance*)-1) {AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(bp_inst->GetType()==0) return 0;
	CaplAttrValue tst_values[2];
	aplExtent ext;
	
	tst_values[0].value.Set(item);
	tst_values[0].attr=a_bp_inst_ref_item;

	tst_values[1].value.Set(bp_inst);
	tst_values[1].attr=a_bp_inst_ref_process;

	m_data->NET_FindInstancesWithAttrValues(e_bp_inst_ref,2,&tst_values[0],ext,true);

	if(ext.Size==0) return 0;
	CaplInstance *rel=ext[0];
	if(rel->GetId()==0) return rel;

	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		int i=ld.AddQuery(-1,rel,true);
		ld.AddQuery(_T('d'), i, 0,a_bp_inst_ref_item, true);
		ld.AddQuery(_T('d'), i, 0,a_bp_inst_ref_process, true);
		ld.LoadEx();
	}
	return rel;
}
///
CaplInstance *CaplBPManager::CheckMyLock(CaplInstance *bp, bool bShowMessages)
{
	if(!m_bUseVersions) return 0;
	if(bp==0) return 0;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(bp->GetAccessmode()>aplRO) return 0;
	
	CaplInstance *lock=GetLock(bp,bShowMessages);
	if(!lock) return 0;

	CaplInstance *user=0;
	m_data->GetAttr(lock,a_bp_ver_author,user);
	CString bp_id=_T("");
	m_data->GetAttr(bp,a_bp_id,bp_id);
	if(user!=m_data->GetCurrUser())
	{
		if(bShowMessages && m_api->m_ModeInteractive)AfxMessageBox( APL_T("Бизнес-процесс ")+bp_id+ APL_T(" заблокирован другим пользователем !"),MB_OK|MB_ICONSTOP);
		return 0;
	}
	return lock;
}

/// Взять бизнес-процесс на редактирование 
bool CaplBPManager::CheckOut( CaplInstance *bp,bool recursive)
{
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(m_data==0) return false;
	if(e_bp==0) return false;
	if(e_apl_bp_ver==0)return false;
	if(!m_bUseVersions) return false;
	if(bp->GetAccessmode()>aplRO)
	{
		if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp);
		return false;
	}
	if(!recursive) m_status_count=0;
	if(m_data->IsKindOf(bp,e_bp))
		if(bp->GetAccessmode()>=aplRO){if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp);return false;}
	if(!m_data->IsKindOf(bp,e_bp))
		if(!m_data->IsKindOf(bp,e_apl_bp_ver))
			return false;
		if(!recursive) {m_data->ClearLastQuery();LoadBPInfo(bp,false);}
	else
	{
		if(m_api->m_ModeInteractive)
		{
			if(!m_status_dlg_created)
			{
				if(!m_status_dlg.m_hWnd) m_status_dlg.Create(IDD_DISASM_STATUS); 
				m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
				m_status_dlg_created=true;
				m_status_count=0;
			}
			if(m_status_dlg_created)
			{
				m_status_dlg.ShowWindow(SW_SHOW);
			}
		}
	}

	CString id,name,descr,code,label,buf;
	CaplInstance *lock=0,*bp_ver_bp=0,*rev=0;
	CaplAggr aggr_elem,aggr_res,aggr_char_val,aggr_new_char_val,aggr_old_char_val;
	CaplInstance *bp_type=0;
	aplExtent ext_char_to_check_out,ext_char_to_edit;
	CaplInstance *act=0,*bp_to_check_out=0;

	CString bp_id=_T("");
	if(m_data->IsKindOf(bp,e_bp))
		bp_to_check_out=bp;
	else if(m_data->IsKindOf(bp,e_apl_bp_ver))
	{
		rev=bp;
		m_data->GetAttr(bp,a_bp_ver_bp,bp_ver_bp);
		if(!bp_ver_bp) return false;
		if(bp_ver_bp->GetAccessmode()>=aplRO) 
		{	
			if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp_ver_bp);
			return false;
		}
		bp_to_check_out=bp_ver_bp;
	}
	m_data->GetAttr(bp_to_check_out,a_bp_lock,lock);
	m_data->GetAttr(bp_to_check_out,a_bp_id,bp_id);
	m_data->GetAttr(bp_to_check_out,a_bp_act,act);

	if(lock!=0)
	{
		CaplInstance *user=0;
		m_data->GetAttr(lock,a_bp_ver_author,user);
		if(user!=m_data->GetCurrUser())
		{
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Бизнес-процесс ")+bp_id+ APL_T(" уже редактируется !"),MB_OK|MB_ICONSTOP);
		}
		return false;
	}
	if(!act)
	{
		CString num=_T("");
		act=GetLatestBPVersion(bp_to_check_out,num);
		if(act)
			m_data->PutAttr(bp_to_check_out,a_bp_act,act);
		else
		{
			aplExtent ext_char,ext_group;
			m_api->m_charact_mgr.FindAssociatedCharacteristic(bp_to_check_out,ext_char,ext_group,true);
			act=CreateBPVersion(bp_to_check_out,_T("0"));
		}
	}

	aplExtent ext_char,ext_group;
	
	if(rev)	
	{
		if(!recursive) m_api->m_charact_mgr.FindAssociatedCharacteristic(rev,ext_char,ext_group,true);
		lock=CreateBPVersion(rev,_T("-1"),false);
	}
	else
	{
		if(!recursive) m_api->m_charact_mgr.FindAssociatedCharacteristic(bp,ext_char,ext_group,true);
		// AY: 22.11.2024 Если версия кривая (меняли БП без создания версии), то атрибуты копировались не те
		//lock=CreateBPVersion(act,_T("-1"),false);
		lock=CreateBPVersion(bp,_T("-1"),false);
	}
	if(!lock) return false;
	m_data->PutAttr(bp_to_check_out,a_bp_lock,lock);
	
	bool old_mode_interactive=m_api->m_ModeInteractive;
	m_api->m_ModeInteractive=false;
	if(m_api->m_charact_mgr.m_bUseVersions)
	{
		bool old_AS_char=m_api->m_charact_mgr.m_AutoSave;
		m_api->m_charact_mgr.m_AutoSave=false;

		m_data->GetAttr(lock,a_bp_ver_char_val_versions,aggr_char_val);
		for(int i=0;i<aggr_char_val.GetSize();i++)
		{
			CaplInstance *inst=0;
			aggr_char_val.GetByIndex(i,inst);
			CaplInstance *char_val=0;
			m_data->GetAttr(inst,m_api->m_charact_mgr.a_apl_charact_val_ver_char_value,char_val);
			if(char_val && char_val->GetAccessmode()<aplRO) m_data->PutAttr(char_val,m_api->m_charact_mgr.a_apl_charact_val_lock_ver,inst);
		}
		//залочим остальные характеристики взятого на редактирование бп
		if((rev && rev!=act))
		{
			aplExtent ext_char,ext_group;
			if(m_api->m_charact_mgr.FindAssociatedCharacteristic(bp_to_check_out,ext_char,ext_group,!recursive,false,!recursive))
			{
				for(int i=0;i<ext_char.GetSize();i++)
				{
					CaplInstance *char_lock=m_api->m_charact_mgr.GetLock(ext_char[i],false);
					if(!char_lock) m_api->m_charact_mgr.CheckOut(ext_char[i]);
				}
			}
		}
		m_api->m_charact_mgr.m_AutoSave=old_AS_char;
	}
	m_api->m_ModeInteractive=old_mode_interactive;

	if(recursive && m_status_dlg_created && m_api->m_ModeInteractive)
	{
		m_status_count++;
		m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
		CString buf;buf.Format(_T("%d"),m_status_count);
		m_status_dlg.m_count.SetWindowText(buf);
	}	
	if(m_AutoSave && !recursive) 
		m_api->SaveChanges();
	
	return true;
}

bool CaplBPManager::CheckOutWithRequest(CaplInstance *bp,bool &recursive)
{
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetAccessmode()>aplRW)
	{
		if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp);
		return false;
	}
	if(!recursive){ 
		m_data->ClearLastQuery();
		LoadBPInfo(bp);
	}

	CString state;
	m_data->GetAttr(bp,a_bp_state,state);
	if(m_api->m_show.m_auto_wfstate!=TRUE)
	{
		if( ! ((state==_T("")) || (state==_T("working"))  || (state==_T("changing"))) )
		{
			if(m_api->m_ModeInteractive) 
			{
				CString sMsg;
				sMsg.Format(_T("%s%s%s%s"),	APL_T("Бизнес-процесс находится в состоянии \""),
											GetWFStateName(state),
											APL_T("\" и не может быть изменен.\n\n"),
											APL_T("Для изменения бизнес-процесс надо перевести в состояние \"в разработке\" или \"на изменении\"."));
				AfxMessageBox(sMsg ,MB_OK|MB_ICONSTOP);
			}
			else
				TRACE( APL_T("Документ находится в состоянии \"")+GetWFStateName(state)+ APL_T("\" и не может быть изменен."));
			
			return false;
		}
	}
	else
	{
		if(state==_T("canceled"))
		{
			if(m_api->m_ModeInteractive) AfxMessageBox( APL_T("Бизнес процесс находится в состоянии \"")+GetWFStateName(state)+ APL_T("\" и не может быть изменен"));
			return false;
		}
		else if(state==_T("approved") || state==_T("approving_change"))
		{
			if(m_api->m_ModeInteractive) 
				if(IDNO==AfxMessageBox( APL_T("Бизнес процесс находится в состоянии \"")+GetWFStateName(state)+ APL_T("\". перевести его в состояние \"")+GetWFStateName("changing")+_T("\""),
				MB_YESNO|MB_ICONQUESTION)) return false;
			
			if(0==ChangeWFState(bp,_T("changing")))return false;
		}
		else if(state==_T("approving"))
		{
			if(m_api->m_ModeInteractive) 
				if(IDNO==AfxMessageBox( APL_T("Бизнес процесс находится в состоянии \"")+GetWFStateName(state)+ APL_T("\". перевести его в состояние \"")+GetWFStateName("changing")+_T("\""),
				MB_YESNO|MB_ICONQUESTION)) return false;
			
			if(0==ChangeWFState(bp,_T("working")))return false;
		}
	}

	// Проверяем Флаг "Унифицированный"
	/* Такая провека не сработает
	if(m_data->IsKindOf(bp,e_bp))
	{
		bool bUnified=false;
		m_data->GetAttr(bp, a_bp_unified, bUnified);
		if(bUnified)
		{
			CaplInstance *parent=0;
			m_data->GetAttr(bp, a_bp_parent, parent);
			if(0!=parent)
			{
				LoadBPInfo(parent);
				bool bParentUnified=false;
				m_data->GetAttr(parent, a_bp_unified, bParentUnified);

				if(!bParentUnified)
				{
					AfxMessageBox( APL_T("Это унифицированный бизнес-процесс.,
					return false;
				}
			}
		}
	}
	*/


	CaplAggr aggr;
	if(m_data->IsKindOf(bp,e_bp)) 
		m_data->GetAttr(bp,a_bp_elements,aggr);
	bool check_out_result=false;
	bool sub_bp_choice_result=false;
	bool do_recursive=false;

	if(aggr.GetSize()) 
	{
		if(recursive)
		{
			do_recursive=true;
		}
		else
		{
			CString sMsg;
			sMsg.Format(_T("%s%s"), APL_T("Бизнес-процесс содержит подпроцессы\n\n"), APL_T("Взять подпроцессы на редактирование ?"));
			if(!m_api->m_ModeInteractive || IDYES==AfxMessageBox( sMsg,MB_YESNO|MB_ICONQUESTION)) do_recursive=true;
		}
	
	}
	if(do_recursive) 
	{
		CChoose_sub_bps_dlg dlg;
		dlg.m_api=m_api;
		dlg.m_bp=bp;
		dlg.m_title= APL_T("Выбор подпроцессов для редактирования");
		if(dlg.DoModal()==IDOK) 
		{
			if(dlg.ext_out.GetSize()) sub_bp_choice_result=true;
		}
		if(!m_status_dlg_created)
		{
			if(m_status_dlg.Create(IDD_DISASM_STATUS)) m_status_dlg_created=true;
		}
		if(m_status_dlg_created)
		{
			m_status_count=0;
			m_status_dlg.ShowWindow(SW_SHOW);
			m_status_dlg.m_name.SetWindowText( APL_T("Загрузка данных..."));
			m_status_dlg.m_count.SetWindowText(_T(""));
		}
		if(sub_bp_choice_result)
		{
			check_out_result=true;
			aplExtent ext_char,ext_group;
			m_api->m_charact_mgr.FindAssociatedCharacteristic(dlg.ext_out,ext_char,ext_group,true);
			bool old_AS=m_AutoSave;
			m_AutoSave=false;
			for(int i=0;i<dlg.ext_out.GetSize();i++)
			{
				if(CheckOut(dlg.ext_out[i],true))
				{
					CaplInstance *lock=0;
					m_data->GetAttr(dlg.ext_out[i],a_bp_lock,lock);
					if(lock) m_data->PutAttr(lock,a_bp_ver_basis,dlg.m_basis);	
				}
			}
			m_AutoSave=old_AS;
		}
	}
	else
	{
		CCheckOutDlg dlg;	
		dlg.m_title= APL_T("Редактирование бизнес-процесса");
		dlg.m_checkout_question= APL_T("Взять бизнес-процесс на редактирование?");
		if(dlg.DoModal()==IDOK)
			check_out_result=CheckOut(bp,false);
		if(check_out_result)
		{
			if(dlg.m_basis!=_T(""))
			{
				CaplInstance *lock=0,*bp_ver_bp=0;
				if(m_data->IsKindOf(bp,e_bp))
					m_data->GetAttr(bp,a_bp_lock,lock);
				else if(m_data->IsKindOf(bp,e_apl_bp_ver))
				{
					m_data->GetAttr(bp,a_bp_ver_bp,bp_ver_bp);	
					if(bp_ver_bp) m_data->GetAttr(bp_ver_bp,a_bp_lock,lock);
				}
				if(lock) 
				{
					m_data->PutAttr(lock,a_bp_ver_basis,dlg.m_basis);	
				}
			}
		}
	}

	if(m_AutoSave) 
		m_api->SaveChanges();
	if(m_status_dlg_created) {m_status_count=0;m_status_dlg.m_count.SetWindowText(_T(""));m_status_dlg.ShowWindow(SW_HIDE);}
	return check_out_result;
}

bool CaplBPManager::CheckInWithRequest(CaplInstance *bp,bool &recursive)
{
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetAccessmode()>aplRW)
	{
		if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp);
		return false;
	}
	if(!m_data->IsKindOf(bp,e_bp)) return false;
	LoadBPInfo(bp);
	aplExtent ext_char,ext_group;
	m_api->m_charact_mgr.FindAssociatedCharacteristic(bp,ext_char,ext_group);
	CaplInstance *lock=CheckMyLock(bp,true);	
	if(!lock) return false;

	// для изменения в дальнейшем характеристики "Расцеховка"

	CaplInstance *iParent = NULL, *iBP = bp;
	// выделяем родительский бизнес-процесс
	do 
	{
		m_api->m_data.GetAttr(iBP, m_api->m_bp_mgr.a_bp_parent, iParent);
		if(iParent != NULL)
			iBP = iParent;
	}
	while(iParent != NULL);

	// ищем pdf 
	CaplAttrValue attr;
	aplExtent ref_ext;
	CaplInstance *ref_item = NULL;
	attr.attr = m_api->m_bp_mgr.a_bp_ref_process;
	attr.value.Set(iBP);
	m_api->m_data.NET_FindInstancesWithAttrValues(m_api->m_bp_mgr.e_bp_ref, 1, &attr, ref_ext, false);
	if(ref_ext.GetSize() > 0)
		m_api->m_data.GetAttr(ref_ext[0], m_api->m_bp_mgr.a_bp_ref_item, ref_item);		
	

	CCheckInDlg dlg;
	dlg.m_title= APL_T("Завершение редактирования бизнес-процесса");
	dlg.m_checkin_question= APL_T("Завершить редактирование бизнес-процесса?");
	dlg.m_make_active=1;
	if(bp->GetAccessmode()>aplRW) 
	{
		dlg.m_make_active=0;
		dlg.m_no_rigths_to_make_active=true;
	}
	CaplAggr aggr,aggr1;
	m_data->GetAttr(bp,a_bp_elements,aggr);
	m_data->GetAttr(lock,a_bp_ver_elements,aggr1);
	if(aggr.GetSize() || aggr1.GetSize()) dlg.m_recursive=1;
	else
	{
		dlg.m_recursive=0;
		if(!aggr.GetSize() && !aggr1.GetSize()) dlg.m_recursive_enabled=false;
	}
	bool check_in_result=false;
	bool make_active=false;

	if(dlg.DoModal()==IDOK)
	{
		recursive=false;
		if(dlg.m_recursive==1) recursive=true;
		if(dlg.m_make_active==1) make_active=true;
		if(recursive)
		{
			aplExtent ext;
			GetAllSubBP(bp,ext);
			LoadBPInfo(ext);
		}
		m_apply_to_all=false;m_undo_check_out=false;
		check_in_result=CheckIn(bp,recursive,make_active);
		m_apply_to_all=false;m_undo_check_out=false;

		//создаем хар-ку пасцеховка по новым значениям БП
		RebuildCharactRasc(ref_item);

	}
	if(m_AutoSave) m_api->SaveChanges();

	return check_in_result;
}

void CaplBPManager::RebuildCharactRasc(CaplInstance *iPDF)
{
	CString sText, buf;
	CaplInstance *iBPType = NULL, *iParent = NULL;
	HMODULE hMod;
					
	//непосредственное создание
#ifndef _DEBUG
#ifdef UNICODE
	hMod = AfxLoadLibrary(_T("CaplCeh_u.dll"));
#else
	hMod = AfxLoadLibrary(_T("CaplCeh.dll"));
#endif
#else
#ifdef UNICODE
	hMod = AfxLoadLibrary(_T("CaplCeh_ud.dll"));	
#else
	hMod = AfxLoadLibrary(_T("CaplCehD.dll"));	
#endif
#endif

	if(hMod!=NULL)
	{
		bool (*CreateRascAfterCheckIn)(CaplAPI*, CaplInstance*);
		(FARPROC&)CreateRascAfterCheckIn = GetProcAddress(hMod, "CreateRascAfterCheckIn"); //-V614
		if(!CreateRascAfterCheckIn){
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Дополнение не содержит исполняемой функции."));
		}else
			CreateRascAfterCheckIn(m_api, iPDF);
		
		AfxFreeLibrary(hMod);
	}		
}

bool CaplBPManager::UndoCheckOutWithRequest(CaplInstance *bp,bool &recursive)
{
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetAccessmode()>aplRW)
	{
		if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp);
		return false;
	}
	if(!m_data->IsKindOf(bp,e_bp)) return false;
	LoadBPInfo(bp);
	
	CaplInstance *lock=0;
	if(bp->GetAccessmode()>aplOWN)
	{
		lock=CheckMyLock(bp,true);	
		if(!lock) return false;
	}
	else
	{
		m_data->GetAttr(bp,a_bp_lock,lock);
		if(!lock)
		{
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Бизнес-процесс не заблокирован!"));
			return false;
		}
	}

	CCheckInDlg dlg;
	dlg.m_title= APL_T("Отмена редактирования бизнес-процесса");
	dlg.m_checkin_question= APL_T("Отменить редактирование бизнес-процесса?");
	dlg.m_make_active_enabled=false;
	CaplAggr aggr,aggr1;
	m_data->GetAttr(bp,a_bp_elements,aggr);
	m_data->GetAttr(lock,a_bp_ver_elements,aggr1);
	if(aggr.GetSize() || aggr1.GetSize()) dlg.m_recursive=1;
	else
	{
		dlg.m_recursive=0;
		if(!aggr.GetSize() && !aggr1.GetSize()) dlg.m_recursive_enabled=false;
	}
	bool undo_check_out_result=false;

	if(dlg.DoModal()==IDOK)
	{
		recursive=false;
		if(dlg.m_recursive==1) recursive=true;
		if(recursive)
		{
			aplExtent ext;
			GetAllSubBP(bp,ext);
			LoadBPInfo(ext);

		}
		m_apply_to_all=false;m_undo_check_out=false;
		undo_check_out_result=UndoCheckOut(bp,recursive);
		m_apply_to_all=false;m_undo_check_out=false;
	}
	if(m_AutoSave) m_api->SaveChanges();
	return undo_check_out_result;
}

/// Завершить  редактирование бизнес-процесса
bool CaplBPManager::CheckIn( CaplInstance *bp,bool recursive,bool make_new_version_active)
{
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(m_data==0) return false;
	if(e_bp==0) return false;
	if(e_apl_bp_ver==0)return false;
	if(!m_bUseVersions) return false;
	if(bp->GetType()==0) return false;

	aplExtent ext_char,ext_group;
	if(!recursive) 
	{
		LoadBPInfo(bp,false);
		m_api->m_charact_mgr.FindAssociatedCharacteristic(bp,ext_char,ext_group,true);
	}
	else
	{
		if(!m_status_dlg_created)
		{
			if(!m_status_dlg.m_hWnd) m_status_dlg.Create(IDD_DISASM_STATUS); 
			m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
			m_status_dlg_created=true;
			m_status_count=0;
		}
		if(m_status_dlg_created)
		{
			m_status_dlg.ShowWindow(SW_SHOW);
		}
	}

	if(!m_data->IsKindOf(bp,e_bp))
	{
		if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
		return false;
	}
	if(bp->GetAccessmode()>aplRO)
	{
		if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp);
		if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
		return false;
	}
	CaplInstance *lock=CheckMyLock(bp,false);
	if(recursive)
	{
		aplExtent ext_sub_old,ext_sub_new;
		CaplInstance *inst=0,*inst0=0;
		m_data->GetAttr(bp,a_bp_elements,ext_sub_old);
		m_api->m_charact_mgr.FindAssociatedCharacteristic(ext_sub_old,ext_char,ext_group,true);
		for(int i=0;i<ext_sub_old.GetSize();i++)
		{
			m_level++;
			CheckIn(ext_sub_old[i],true,make_new_version_active);
			m_level--;			
		}

		if(lock)
		{
			if(lock->GetAccessmode()<aplNO)
			{
				m_data->GetAttr(lock,a_bp_ver_elements,ext_sub_new);
				m_api->m_charact_mgr.FindAssociatedCharacteristic(ext_sub_new,ext_char,ext_group,true);
				for(int i=0;i<ext_sub_new.GetSize();i++)
				{
					bool found=false;
					for(int j=0;j<ext_sub_old.GetSize();j++)
					{
						if(ext_sub_old[j]==ext_sub_new[i])	{found=true;break;}
					}
					if(!found) 
					{
						m_level++;
						CheckIn(ext_sub_new[i],true,make_new_version_active);
						m_level--;
					}
				}
			}
		}
	}
	if(bp->GetAccessmode()>=aplRO) 	
	{
		if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
		return false;
	}
	if(lock==0) 
	{
		if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
		return false;
	}
	m_api->m_charact_mgr.FindAssociatedCharacteristic(bp,ext_char,ext_group,false,false,false);

	CString bp_id=_T("");
	m_data->GetAttr(bp,a_bp_id,bp_id);

	CString buf;
	CString version_guid;
	CaplAggr aggr,aggr0,aggr1,aggr2,aggr_old_char_val_ver,aggr_char_val_ver,aggr_new_char_val;
	CaplInstance *bp_type0=0,*base=0,*act=0;
	aplExtent ext_res;
	int i,j;

	m_data->GetAttr(lock,a_bp_ver_elements,aggr);
	m_data->GetAttr(lock,a_bp_ver_res,aggr1);
	m_data->GetAttr(lock,a_bp_ver_char_val_versions,aggr_char_val_ver);
	m_data->GetAttr(lock,a_bp_ver_base,base);

	m_data->GetAttr(bp,a_bp_act,act);

	if(!make_new_version_active)
	{
		if(lock==act) make_new_version_active=true;//если активная и локер версия совпадают, то это первая версия
	}
	if(act) 
	{
		m_data->GetAttr(act,a_bp_ver_char_val_versions,aggr_old_char_val_ver);
	}

	CaplInstance *inst=0,*inst0=0,*inst1=0;
	aplExtent ext_ver_counter;
	
	bool old_mode_interactive_char=m_api->m_ModeInteractive;
	m_api->m_ModeInteractive=false;
	m_api->m_charact_mgr.LoadCharacteristic(aggr_char_val_ver);
	if(base)
	{
		if(!IsBPChanged(bp,lock))
		{
			if(!m_apply_to_all)
			{
				CApplyToAllDlg c_appl_dlg;
				if(!recursive) c_appl_dlg.m_apply_to_all_enabled=false;
				c_appl_dlg.m_question= APL_T("Данные процесса ")+bp_id+ APL_T(" не изменились !\n\nОтменить редактирование ?");
				int dlg_result=c_appl_dlg.DoModal();
				if(c_appl_dlg.m_apply_to_all)
				{
					m_apply_to_all=true;
				}
				if(dlg_result==IDOK) m_undo_check_out=true;
				else m_undo_check_out=false;
			}
			if(!m_undo_check_out) 
			{
				if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
				m_api->m_ModeInteractive=old_mode_interactive_char;
				return false;
			}
								
			// Отмена редактирования
			//bool old_mode_interactive=m_api->m_ModeInteractive;
			//m_api->m_ModeInteractive=false;
			UndoCheckOut(bp);
			//m_api->m_ModeInteractive=old_mode_interactive;
		
			if(recursive && m_status_dlg_created)
			{
				m_status_count++;
				m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
				CString buf;buf.Format(_T("%d"),m_status_count);
				m_status_dlg.m_count.SetWindowText(buf);
			}
			if(m_AutoSave && !recursive) 
				m_api->SaveChanges();
			if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
			m_api->m_ModeInteractive=old_mode_interactive_char;
			return true;
		}
	}


	//Завершение редактирования характеристик
	bool old_AS_char=m_api->m_charact_mgr.m_AutoSave;
	m_api->m_charact_mgr.m_AutoSave=false;

	//разблокирование характеристик, которых нет в новом списке
	if(m_api->m_charact_mgr.m_bUseVersions)
	{
		for(int i=0;i<ext_char.GetSize();i++)
		{
			CaplInstance *char_lock=m_api->m_charact_mgr.GetLock(ext_char[i],false);
			
			bool bFound=false;
			for(j=0;j<aggr_char_val_ver.GetSize();j++)
			{
				aggr_char_val_ver.GetByIndex(j,inst0);
				if(char_lock==inst0) 
				{
					bFound=true;
					break;
				}
			}
			if(!bFound)
			{
				m_api->m_charact_mgr.UndoCheckOut(ext_char[i],false);
			}
		}
	}
	//собственно завершение редактирования характеристик
	bool aggr_changed=false;
	for(i=0;i<aggr_char_val_ver.GetSize();i++)
	{
		CaplInstance *inst=0;
		aggr_char_val_ver.GetByIndex(i,inst);
		if(!inst) continue;
		if(!inst->GetType()) continue;
		CaplInstance *char_value=0;
		CaplInstance *base=0;
		m_data->GetAttr(inst,m_api->m_charact_mgr.a_apl_charact_val_ver_base,base);
		m_data->GetAttr(inst,m_api->m_charact_mgr.a_apl_charact_val_ver_char_value,char_value);
		if(!char_value) continue;
		if(char_value->GetAccessmode()>aplRW) continue;
		bool is_val_changed=false;
		m_data->GetAttr(inst,m_api->m_charact_mgr.a_apl_charact_val_ver_is_changed,is_val_changed);
		if(is_val_changed)
		{
			m_api->m_charact_mgr.CheckIn(char_value,false);
		}
		else
		{
			m_api->m_charact_mgr.UndoCheckOut(char_value,false);
			if(base)
			{
				CaplValue capl_val;
				capl_val.Set(base);
				aggr_char_val_ver.Insert(i,capl_val);
				aggr_changed=true;
			}
		}
	}
	if(aggr_changed) m_data->PutAttr(lock,a_bp_ver_char_val_versions,aggr_char_val_ver);

	m_api->m_charact_mgr.m_AutoSave=old_AS_char;

	CaplInstance *new_active_version=0;
	CString basis=_T("");

	COleDateTime dt=COleDateTime::GetCurrentTime();
	aplDate2String(dt,buf);
	m_data->PutAttr(lock,a_bp_ver_end,buf);

	//определение id версии
	if(act==lock)
	{
		buf=_T("0");
	}
	else
	{
		GetLatestBPVersion(bp,buf);
		int max_id=_atoi(buf);
		max_id++;
		buf.Format(_T("%i"),max_id);
	}
	m_data->PutAttr(lock,a_bp_ver_num,buf);


	m_data->GetAttr(lock,a_bp_ver_basis,basis);

	if(make_new_version_active)
	{
		MakeBPVersionActive(lock);
	}
	m_data->PutAttr(bp,a_bp_lock,(CaplInstance*)0);

	if(recursive && m_status_dlg_created)
	{
		m_status_count++;
		m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
		CString buf;buf.Format(_T("%d"),m_status_count);
		m_status_dlg.m_count.SetWindowText(buf);
		if(m_level==0) 
		{
			m_status_dlg.ShowWindow(SW_HIDE);
			m_status_count=0;
			m_status_dlg.m_count.SetWindowText(_T(""));
		}
	}
		
	if(m_AutoSave && !recursive)
		m_api->SaveChanges();
	
	m_api->m_ModeInteractive=old_mode_interactive_char;
	
	return true;
}

bool CaplBPManager::UndoCheckOut( CaplInstance *bp,bool recursive)
{
	int i;
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(m_data==0) return false;
	if(e_bp==0) return false;
	if(!m_data->IsKindOf(bp,e_bp))return false;
	if(!m_bUseVersions) return false;
	if(bp->GetAccessmode()>aplRO) return false;
	if(!recursive) LoadBPInfo(bp,false);
	else
	{
		if(!m_status_dlg_created)
		{
			if(!m_status_dlg.m_hWnd) m_status_dlg.Create(IDD_DISASM_STATUS); 
			m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
			m_status_dlg_created=true;
			m_status_count=0;
		}
		if(m_status_dlg_created)
		{
			m_status_dlg.ShowWindow(SW_SHOW);
		}
	}
	//11_05_2004 по заявке КВЗ .Внес dmibor
	bool old_mode_interactive=m_api->m_ModeInteractive;
	m_api->m_ModeInteractive=false;

	CaplInstance *lock,*user;
	m_data->GetAttr(bp,a_bp_lock,lock);
	aplExtent ext,ext_char,ext_group;
	if(recursive)
	{
		CaplInstance *inst=0;
		m_data->GetAttr(bp,a_bp_elements,ext);
		m_api->m_charact_mgr.FindAssociatedCharacteristic(ext,ext_char,ext_group,true);
		for(int i=0;i<ext.GetSize();i++)
		{
			m_level++;
			UndoCheckOut(ext[i],true);
			m_level--;
		}
		if(lock)
		{
			if(lock->GetAccessmode()<aplNO)
			{
				m_data->GetAttr(lock,a_bp_ver_elements,ext);
				m_api->m_charact_mgr.FindAssociatedCharacteristic(ext,ext_char,ext_group,true);
				for(int i=0;i<ext.GetSize();i++)
				{
					m_level++;
					UndoCheckOut(ext[i],true);
					m_level--;
				}
			}
		}

	}
	if(bp->GetAccessmode()>aplRW) 
	{
		if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
		m_api->m_ModeInteractive=old_mode_interactive;
		return false;
	}
	if(!lock) 
	{
		if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
		m_api->m_ModeInteractive=old_mode_interactive;
		return false;
	}
	m_data->GetAttr(lock,a_bp_ver_author,user);
	CString bp_id=_T("");
	m_data->GetAttr(bp,a_bp_id,bp_id);
	if(user!=m_data->GetCurrUser())
	{
		if(bp->GetAccessmode()>aplOWN) 
		{
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Бизнес-процесс ")+bp_id+ APL_T(" заблокирован другим пользователем !"),MB_OK|MB_ICONSTOP);
			if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
			m_api->m_ModeInteractive=old_mode_interactive;
			return false;
		}
		if(!m_apply_to_all)
		{
			CApplyToAllDlg c_appl_dlg;
			c_appl_dlg.m_question= APL_T("Бизнес-процесс ")+bp_id+ APL_T(" заблокирован другим пользователем !\n\nВсе равно отменить редактирование ?");
			int dlg_result=c_appl_dlg.DoModal();
			if(c_appl_dlg.m_apply_to_all)
			{
				m_apply_to_all=true;
			}
			if(dlg_result==IDOK) m_undo_check_out=true;
			else m_undo_check_out=false;
			
		}
		if(!m_undo_check_out) 
		{
			if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
			m_api->m_ModeInteractive=old_mode_interactive;
			return false;
		}
	}
	//если это первая еще не утвержденная версия 
	CaplInstance *act=0;
	m_data->GetAttr(bp,a_bp_act,act);
	if(act==lock) 
	{
		CheckIn(bp);
		if(recursive && m_status_dlg_created)
		{
			m_status_count++;
			m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
			CString buf0;buf0.Format(_T("%d"),m_status_count);
			m_status_dlg.m_count.SetWindowText(buf0);
		}
		if(m_status_dlg_created && m_level==0) {m_status_dlg.ShowWindow(SW_HIDE);m_status_count=0;}
		m_api->m_ModeInteractive=old_mode_interactive;
		return true;
	}

	//удаление ресурсов локера
	CaplAggr aggr,aggr0;
	CaplInstance *base_version=0;
	m_data->GetAttr(lock,a_bp_ver_res,aggr);
	m_data->GetAttr(lock,a_bp_ver_base,base_version);
	if(base_version)
	{
		//LoadBPInfo(base_version,false);
		m_data->GetAttr(base_version,a_bp_ver_res,aggr0);
	}
	else
		m_data->GetAttr(bp,a_bp_res,aggr0);
	CaplInstance *base_res,*res;
	for(i=0;i<aggr.GetSize();i++)
	{
		bool res_found=false;
		aggr.GetByIndex(i,res);
		for(int j=0;j<aggr0.GetSize();j++)
		{
			aggr0.GetByIndex(j,base_res);
			if(res==base_res)	{res_found=true;break;}
		}
		if(!res_found) m_data->DeleteInstance(res);
	}
	//удаление версий характеристик
	if(m_api->m_charact_mgr.m_bUseVersions) 
	{
		bool old_AS_char=m_api->m_charact_mgr.m_AutoSave;
		m_api->m_charact_mgr.m_AutoSave=false;

		CaplAggr aggr_char_val_ver,aggr_old_char_val_ver;
		m_data->GetAttr(bp,a_bp_act,act);
		if(act) m_data->GetAttr(act,a_bp_ver_char_val_versions,aggr_old_char_val_ver);
		m_data->GetAttr(lock,a_bp_ver_char_val_versions,aggr_char_val_ver);

		aplExtent ext_char_ver;
		CaplInstance *char_ver=0,*char_val=0;

		for(i=0;i<aggr_char_val_ver.GetSize();i++)
		{
			CaplInstance *inst=0;
			CaplInstance *char_ver_char_value=0;
			aggr_char_val_ver.GetByIndex(i,inst);
			if(!inst) continue;
			if(inst->GetAccessmode()>aplRO) continue;
			m_data->GetAttr(inst,m_api->m_charact_mgr.a_apl_charact_val_ver_char_value,char_ver_char_value);
			if(!char_ver_char_value) continue;
			if(char_ver_char_value->GetAccessmode()>aplRW) continue;
			bool bFound=false;
			for(int j=0;j<aggr_old_char_val_ver.GetSize();j++)
			{
				CaplInstance *inst0=0,*old_char_val=0;
				aggr_old_char_val_ver.GetByIndex(j,inst0);
				if(!inst0) continue; if(inst0->GetAccessmode()>aplRO) continue;
				m_data->GetAttr(inst0,m_api->m_charact_mgr.a_apl_charact_val_ver_char_value,old_char_val);
				if(old_char_val==char_ver_char_value)  {bFound=true;break;}
			}
			m_api->m_charact_mgr.UndoCheckOut(char_ver_char_value,false);
			if(!bFound) //если хар-ка не найдена в старом списке, надо порвать связь с бп
				m_data->PutAttr(char_ver_char_value,m_api->m_charact_mgr.a_apl_charact_val_item,(CaplInstance*)0);
		}
		//разлочим остальные характеристики взятого на редактирование бп
		aplExtent ext_char,ext_group;
		m_api->m_charact_mgr.FindAssociatedCharacteristic(bp,ext_char,ext_group,!recursive,false,!recursive);
		for(i=0;i<ext_char.GetSize();i++)
		{
			CaplInstance *char_lock=m_api->m_charact_mgr.GetLock(ext_char[i],false);
			if(char_lock) m_api->m_charact_mgr.UndoCheckOut(ext_char[i],false);
		}
		m_api->m_charact_mgr.m_AutoSave=old_AS_char;
	}
	m_data->PutAttr(bp,a_bp_lock,(CaplInstance*)0);
	m_data->DeleteInstance(lock);
	if(recursive && m_status_dlg_created)
	{
		m_status_count++;
		m_status_dlg.m_name.SetWindowText( APL_T("Обработано процессов:"));
		CString buf;buf.Format(_T("%d"),m_status_count);
		m_status_dlg.m_count.SetWindowText(buf);
		if(m_level==0) 
		{
			m_status_dlg.ShowWindow(SW_HIDE);
			m_status_count=0;
			m_status_dlg.m_count.SetWindowText(_T(""));
		}
	}
	if(m_AutoSave && !recursive)
		m_api->SaveChanges();
	m_api->m_ModeInteractive=old_mode_interactive;

	return true;
}

/// Добавляет бизнес-процесс в другой бизнес-процесс
bool CaplBPManager::AddBPToBP(CaplInstance *sub_bp, CaplInstance *base_bp)
{
	int i;
	if(m_data==0) return false;
	if(e_bp==0) return false;
	
	if(base_bp==0) return false;
	if(base_bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(base_bp->GetType()==0) return false;
	if(base_bp->GetAccessmode()>aplRW){if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),base_bp); return false;}

	if(sub_bp==0) return false;
	if(sub_bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(sub_bp->GetType()==0) return false;
	if(sub_bp->GetAccessmode()>aplRO){if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),sub_bp); return false;}

	if(base_bp==sub_bp)
	{
		if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Вхождение \"сам в себя\" недопустимо !!!"));
		return false;
	}

	CaplInstance *lock=0;
	if(m_bUseVersions)
	{
		lock=CheckMyLock(base_bp,true);
		if(!lock) return false;
	}
	
	// Проверка повтора
	CaplAggr aggr0;
	if(m_bUseVersions)
		m_data->GetAttr(lock,a_bp_ver_elements,aggr0);
	else
		m_data->GetAttr(base_bp,a_bp_elements,aggr0);
	for(i=0;i<aggr0.GetSize();i++)
	{
		CaplInstance *inst;
		aggr0.GetByIndex(i,inst);
		if(inst==sub_bp)
		{
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Повторное вхождение недопустимо !!!"));
			return false;
		}
	}
	// проверка цикла
	aplExtent ext0,ext1,ext2;
	ext0.Add(base_bp);
	while(ext0.Size>0)
	{
		ext1.Clear();
		ext2.Clear();
		ext2.Append(ext0);
		ext0.Clear();
		for(i=0;i<ext2.Size;i++)
		{
			WhereUsedBP(ext2[i],ext1);
			if(ext1.Find(sub_bp)>=0)
			{
				if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Цикл в структуре бизнес-процессов недопустим !!!"));
				return false;
			}
			ext0.Append(ext1);
		}
	}
	
	aggr0.Add(sub_bp);
	if(m_bUseVersions)
		m_data->PutAttr(lock,a_bp_ver_elements,aggr0);
	else
		m_data->PutAttr(base_bp,a_bp_elements,aggr0);
	if(m_AutoSave) m_api->SaveChanges();
	return true;
}

/// Добавляет экземпляр бизнес-процесса в другой экземпляр бизнес-процесса
bool CaplBPManager::AddBPInstToBPInst(CaplInstance *sub_bp_inst, CaplInstance *base_bp_inst)
{
	int i;
	if(m_data==0) return false;
	
	if(base_bp_inst==0) return false;
	if(base_bp_inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(base_bp_inst->GetType()==0) return false;
	if(base_bp_inst->GetAccessmode()>aplRW){if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),base_bp_inst); return false;}

	if(sub_bp_inst==0) return false;
	if(sub_bp_inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(sub_bp_inst->GetType()==0) return false;
	if(sub_bp_inst->GetAccessmode()>aplRO){if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),sub_bp_inst); return false;}

	if(base_bp_inst==sub_bp_inst)
	{
		if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Вхождение \"сам в себя\" недопустимо !!!"));
		return false;
	}

	// Проверка повтора
	CaplAggr aggr0;
	m_data->GetAttr(base_bp_inst,a_bp_inst_elements,aggr0);
	for(i=0;i<aggr0.GetSize();i++)
	{
		CaplInstance *inst;
		aggr0.GetByIndex(i,inst);
		if(inst==sub_bp_inst)
		{
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Повторное вхождение недопустимо !!!"));
			return false;
		}
	}
	// проверка цикла
	aplExtent ext0,ext1,ext2;
	ext0.Add(base_bp_inst);
	while(ext0.Size>0)
	{
		ext1.Clear();
		ext2.Clear();
		ext2.Append(ext0);
		ext0.Clear();
		for(i=0;i<ext2.Size;i++)
		{
			WhereUsedBPInst(ext2[i],ext1);
			if(ext1.Find(sub_bp_inst)>=0)
			{
				if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Цикл в структуре экземпляров бизнес-процессов недопустим !!!"));
				return false;
			}
			ext0.Append(ext1);
		}
	}
	
	aggr0.Add(sub_bp_inst);
	m_data->PutAttr(base_bp_inst,a_bp_inst_elements,aggr0);
	if(m_AutoSave) m_api->SaveChanges();
	return true;
}

/// Проверяет,взят ли бизнес-процесс на редактирование текущим пользователем
bool CaplBPManager::CheckMyLockAndCheckOut(CaplInstance *bp)
{
	if(!m_bUseVersions) return false;
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(bp->GetAccessmode()>aplRO) return false;

	CaplInstance *lock=0,*user=0,*bp_ver_bp=0;;
	if(m_data->IsKindOf(bp,e_bp))
		m_data->GetAttr(bp,a_bp_lock,lock);
	else if(m_data->IsKindOf(bp,e_apl_bp_ver))
	{
		m_data->GetAttr(bp,a_bp_ver_bp,bp_ver_bp);
		if(bp_ver_bp) m_data->GetAttr(bp_ver_bp,a_bp_lock,lock);
	}
		
	if(lock==0)
	{
		if(m_api->m_ModeInteractive){
			if(IDNO==AfxMessageBox( APL_T("Бизнес-процесс не заблокирован !\n\nЗаблокировать ?"),MB_YESNO|MB_ICONQUESTION))
				return false;
		}
		if(!CheckOutWithRequest(bp)) 
			return false;
	}
	else
	{
		m_data->GetAttr(lock,a_bp_ver_author,user);
		if(user!=m_data->GetCurrUser())
		{
			if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Бизнес-процесс заблокирован другим пользователем !"),MB_OK|MB_ICONSTOP);
			return false;
		}
	}
	return true;
}

//*************************************************************
bool CaplBPManager::GetAllBPVersion(CaplInstance *bp,aplExtent &outExt)
{
	outExt.Clear();
	if(e_bp==0) return false;
	if(m_data==0) return false;
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(!m_bUseVersions) return false;

	int i,j;
	if(bp->GetId()!=0)
	{
		if(m_data->IsConnected())
		{
			// Чтение из базы
			CaplLoadData ld(m_data,DEF_SOURCE);
			// документ
			if(m_data->IsKindOf(bp,e_bp))
				j=ld.AddQuery(_T('b'), bp->GetId(), e_apl_bp_ver,a_bp_ver_bp, true);
			else if(m_data->IsKindOf(bp,e_apl_bp_ver))
				j=ld.AddQuery(_T('b'), bp->GetId(), e_apl_bp_ver,a_bp_ver_base, true);
			  ld.AddQuery(_T('d'), j, 0, a_bp_ver_bp, true);
			  ld.AddQuery(_T('d'), j, 0, a_bp_ver_base, true);
			ld.LoadEx();
		}
	}
	CaplInstance *inst;
	aplExtent ext_hist;
	// Чтение версий
	m_data->GetEntityExtent(e_apl_bp_ver,ext_hist);
	for(i=0;i<ext_hist.Size;i++)
	{
		if(ext_hist[i]==0) continue;
		if(ext_hist[i]->GetType()==0) continue;
		if(ext_hist[i]->GetAccessmode()>aplRO) continue;
		if(m_data->IsKindOf(bp,e_bp))
			m_data->GetAttr(ext_hist[i],a_bp_ver_bp,inst);
		else if(m_data->IsKindOf(bp,e_apl_bp_ver))
			m_data->GetAttr(ext_hist[i],a_bp_ver_base,inst);
		if(inst==bp) 
			outExt.Add(ext_hist[i]);
	}
	LoadBPInfo(outExt);
	return true;
}

//*************************************************************
bool CaplBPManager::GetAllBPVersion(aplExtent& bp_ext,aplExtent &outExt)
{
	outExt.Clear();
	if(e_bp==0) return false;
	if(m_data==0) return false;
	if(bp_ext.GetSize()==0) return false;
	if(!m_bUseVersions) return false;

	int i,j;
	CaplInstance* bp=0;
	if(m_data->IsConnected())
	{
		// Чтение из БД
		CaplLoadData ld_bp(m_data,DEF_SOURCE);
		CaplLoadData ld_bpv(m_data,DEF_SOURCE);
		for(i=0;i<bp_ext.GetSize();i++){
			bp=bp_ext[i];
			if(m_data->IsKindOf(bp,e_bp))
				j=ld_bp.AddQuery(0, bp);
			else if(m_data->IsKindOf(bp,e_apl_bp_ver))
				j=ld_bpv.AddQuery(0,bp);
		}
		if(ld_bp.m_queries.Size>0){
			j=ld_bp.AddQuery(_T('r'), 0, e_apl_bp_ver,a_bp_ver_bp, true);
			ld_bp.AddQuery(_T('d'), j, 0, a_bp_ver_bp, true);
			ld_bp.LoadEx();
			ld_bp.ClearQuery();
		}
		if(ld_bpv.m_queries.Size>0){
			j=ld_bpv.AddQuery(_T('r'), bp->GetId(), e_apl_bp_ver,a_bp_ver_base, true);
			ld_bpv.AddQuery(_T('d'), j, 0, a_bp_ver_bp, true);
			ld_bpv.AddQuery(_T('d'), j, 0, a_bp_ver_base, true);
			ld_bpv.LoadEx();
			ld_bpv.ClearQuery();
		}
	}

	CaplInstance *inst;
	aplExtent ext_hist;
	// Чтение версий
	m_data->GetEntityExtent(e_apl_bp_ver,ext_hist);
	CSortClass::SortExtentByInst(bp_ext);
	for(i=0;i<ext_hist.Size;i++)
	{
		if(ext_hist[i]==0) continue;
		if(ext_hist[i]->GetType()==0) continue;
		if(ext_hist[i]->GetAccessmode()>aplRO) continue;
		if(m_data->IsKindOf(bp,e_bp))
			m_data->GetAttr(ext_hist[i],a_bp_ver_bp,inst);
		else if(m_data->IsKindOf(bp,e_apl_bp_ver))
			m_data->GetAttr(ext_hist[i],a_bp_ver_base,inst);
		if(aplQFindInstInExtent(bp_ext,inst)!=-1){ 
			outExt.Add(ext_hist[i]);
		}
	}
	LoadBPInfo(outExt);
	return true;
}

CaplInstance *CaplBPManager::GetLatestBPVersion(CaplInstance *bp,CString &num)
{
	int j;
	if(bp==0) return 0;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(bp->GetType()==0) return 0;
	
	if(m_data->IsConnected() && bp->GetId()!=0)
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		j=ld.AddQuery(_T('b'), bp->GetId(), e_apl_bp_ver,a_bp_ver_bp, true);
		  ld.AddQuery(_T('d'), j, 0,a_bp_ver_bp, true);
		  ld.AddQuery(_T('d'), j, 0,a_bp_ver_num, true);
		  ld.LoadEx();
	}
    CaplInstance *latest_ver=0,*inst=0;
	int max_id=-1;
	aplExtent ext_rev;
	CString buf;
	num=_T("-1");
	m_data->GetEntityExtent(e_apl_bp_ver,ext_rev);
	for(int i=0;i<ext_rev.Size;i++)
	{
		if(!ext_rev[i]) continue;
		if(ext_rev[i]->GetAccessmode()>aplRO) continue;
		m_data->GetAttr(ext_rev[i],a_bp_ver_bp,inst);
		if(inst==bp)
		{
			j=-1;
			m_data->GetAttr(ext_rev[i],a_bp_ver_num,buf);
			if(buf!=_T("")) j=_atoi(buf);
			if(j>max_id)
			{
				latest_ver=ext_rev[i];
				max_id=j;
				num.Format(_T("%i"),max_id);
			}
		}
	}
	return latest_ver;
}

CaplInstance *CaplBPManager::CreateBPVersion(CaplInstance *bp,CString num,bool make_active)
{
	if(!m_bUseVersions) return 0;
	if(bp==0) return 0;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(bp->GetType()==0) return 0;
	if(bp->GetAccessmode()>aplRO) return 0;
	if(!m_data->IsKindOf(bp,e_bp))
		if(!m_data->IsKindOf(bp,e_apl_bp_ver))
			return 0;

	CString id=_T(""),name=_T(""),descr=_T(""),code=_T(""),label=_T(""),date_time=_T("");
	CaplInstance *type=0,*bp_ver_bp=0,*bp_ver_base=0,*act_ver=0;
	CaplAggr aggr_elem,aggr_res,aggr_old_char_val,aggr_new_char_val;

	CString directive,coat;
	double percent_otk, number_of_simultaneously,t_sht,t_pz;
	CaplInstance *inst_class, *inst_org;
	bool bCustomized=false, bOptional=false;

	CaplInstance *ver=m_data->CreateInstance(e_apl_bp_ver);
	if(m_data->IsKindOf(bp,e_bp))
	{
		m_data->GetAttr(bp,a_bp_id,id);	
		m_data->GetAttr(bp,a_bp_name,name);
		m_data->GetAttr(bp,a_bp_descr,descr);
		m_data->GetAttr(bp,a_bp_code,code);
		m_data->GetAttr(bp,a_bp_customized,bCustomized);
		m_data->GetAttr(bp,a_bp_optional,bOptional);
		m_data->GetAttr(bp,a_bp_label,label);
		m_data->GetAttr(bp,a_bp_type,type);
		m_data->GetAttr(bp,a_bp_elements,aggr_elem);
		m_data->GetAttr(bp,a_bp_res,aggr_res);

		m_data->GetAttr(bp,a_bp_org,inst_org);
		m_data->GetAttr(bp,a_bp_class,inst_class);
		m_data->GetAttr(bp,a_bp_percentage_of_otk,percent_otk);
		m_data->GetAttr(bp,a_bp_number_of_simultaneously_processed_parts,number_of_simultaneously);
		m_data->GetAttr(bp,a_bp_t_sht,t_sht);
		m_data->GetAttr(bp,a_bp_t_pz,t_pz);
		m_data->GetAttr(bp,a_bp_coat,coat);
		m_data->GetAttr(bp,a_bp_directive,directive);

		bp_ver_bp=bp;
	}
	else
	{
		m_data->GetAttr(bp,a_bp_ver_id,id);	
		m_data->GetAttr(bp,a_bp_ver_name,name);
		m_data->GetAttr(bp,a_bp_ver_descr,descr);
		m_data->GetAttr(bp,a_bp_ver_code,code);
		m_data->GetAttr(bp,a_bp_ver_customized,bCustomized);
		m_data->GetAttr(bp,a_bp_ver_optional,bOptional);
		m_data->GetAttr(bp,a_bp_ver_label,label);
		m_data->GetAttr(bp,a_bp_ver_type,type);
		m_data->GetAttr(bp,a_bp_ver_elements,aggr_elem);
		m_data->GetAttr(bp,a_bp_ver_res,aggr_res);
		m_data->GetAttr(bp,a_bp_ver_bp,bp_ver_bp);
		bp_ver_base=bp;

		m_data->GetAttr(bp,a_bp_ver_org,inst_org);
		m_data->GetAttr(bp,a_bp_ver_class,inst_class);
		m_data->GetAttr(bp,a_bp_ver_percentage_of_otk,percent_otk);
		m_data->GetAttr(bp,a_bp_ver_number_of_simultaneously_processed_parts,number_of_simultaneously);
		m_data->GetAttr(bp,a_bp_ver_t_sht,t_sht);
		m_data->GetAttr(bp,a_bp_ver_t_pz,t_pz);
		m_data->GetAttr(bp,a_bp_ver_coat,coat);
		m_data->GetAttr(bp,a_bp_ver_directive,directive);
	}

	if(m_api->m_charact_mgr.m_bUseVersions)
	{
		bool old_AS_char=m_api->m_charact_mgr.m_AutoSave;
		m_api->m_charact_mgr.m_AutoSave=false;

		m_data->GetAttr(bp_ver_bp,a_bp_act,act_ver);
		if(bp_ver_base==act_ver || m_data->IsKindOf(bp,e_bp))
		{
			aplExtent ext_char,ext;
			if(m_api->m_charact_mgr.FindAssociatedCharacteristic(bp_ver_bp,ext_char,ext,false,false,false))
			{
				for(int i=0;i<ext_char.GetSize();i++)
					aggr_old_char_val.Add(ext_char[i]);
			}
		}
		else
		{
			m_data->GetAttr(bp,a_bp_ver_char_val_versions,aggr_old_char_val);
			//m_api->m_charact_mgr.LoadCharacteristic(aggr_old_char_val);
		}

		CaplInstance *val=0,*new_ver=0;
		for(int i=0;i<aggr_old_char_val.GetSize();i++)
		{
			aggr_old_char_val.GetByIndex(i,val);
			if(!val) continue;
			if(val->GetAccessmode()>aplRW) //если на характеристику нет доступа 
			{
				m_data->GetAttr(val,m_api->m_charact_mgr.a_apl_charact_val_act_ver,new_ver);
			}
			else
			{
				new_ver=m_api->m_charact_mgr.CreateCharValVersion(val,_T("-1"),make_active);
			}
			if(new_ver)
			{
				aggr_new_char_val.Add(new_ver);
				if(new_ver->GetAccessmode()<aplRO)
					m_data->PutAttr(new_ver,m_api->m_charact_mgr.a_apl_charact_val_ver_item,ver);
			}
		}
		m_api->m_charact_mgr.m_AutoSave=old_AS_char;
	}

	CString guid;
	CaplAPI::CreateGuid(guid);

	m_data->PutAttr(ver,a_bp_ver_id,id);	
	m_data->PutAttr(ver,a_bp_ver_name,name);
	m_data->PutAttr(ver,a_bp_ver_descr,descr);
	m_data->PutAttr(ver,a_bp_ver_code,code);
	m_data->PutAttr(ver,a_bp_ver_customized,bCustomized);
	m_data->PutAttr(ver,a_bp_ver_optional,bOptional);
	m_data->PutAttr(ver,a_bp_ver_label,label);
	m_data->PutAttr(ver,a_bp_ver_type,type);
	m_data->PutAttr(ver,a_bp_ver_elements,aggr_elem);
	m_data->PutAttr(ver,a_bp_ver_res,aggr_res);
	m_data->PutAttr(ver,a_bp_ver_char_val_versions,aggr_new_char_val);
	m_data->PutAttr(ver,a_bp_ver_bp,bp_ver_bp);
	m_data->PutAttr(ver,a_bp_ver_base,bp_ver_base);
	m_data->PutAttr(ver,a_bp_ver_author,m_data->GetCurrUser());
	m_data->PutAttr(ver,a_bp_ver_char_val_versions,aggr_new_char_val);
	m_data->PutAttr(ver,a_bp_ver_guid,guid);

	m_data->PutAttr(ver,a_bp_ver_org,inst_org);
	m_data->PutAttr(ver,a_bp_ver_class,inst_class);
	m_data->PutAttr(ver,a_bp_ver_percentage_of_otk,percent_otk);
	m_data->PutAttr(ver,a_bp_ver_number_of_simultaneously_processed_parts,number_of_simultaneously);
	m_data->PutAttr(ver,a_bp_ver_t_sht,t_sht);
	m_data->PutAttr(ver,a_bp_ver_t_pz,t_pz);
	m_data->PutAttr(ver,a_bp_ver_coat,coat);
	m_data->PutAttr(ver,a_bp_ver_directive,directive);

	COleDateTime dt=COleDateTime::GetCurrentTime();
	aplDate2String(dt,date_time);
	m_data->PutAttr(ver,a_bp_ver_start,date_time);
	if(make_active)
	{
		//назначение номера версии
		m_data->PutAttr(ver,a_bp_ver_end,date_time);
		if(num==_T("-1")) 
		{
			GetLatestBPVersion(bp_ver_bp,num);
			int max_id=_atoi(num);
			max_id++;
			num.Format(_T("%i"),max_id);
		}
		m_data->PutAttr(ver,a_bp_ver_num,num);

		MakeBPVersionActive(ver);
	}
	
	if(m_AutoSave) 
		m_api->SaveChanges();
	return ver;

}

bool CaplBPManager::MakeBPVersionActive(CaplInstance *bp_ver)
{
	int i;
	if(!m_bUseVersions) return false;
	if(bp_ver==0) return false;
	if(bp_ver==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp_ver->GetAccessmode()>aplRO) {if(m_api->m_ModeInteractive)aplErrorMessage(S::NoAccessRight(),bp_ver); return false;}
	if(!m_data->IsKindOf(bp_ver,e_apl_bp_ver))
		return false;

	CaplInstance *bp=0;
	m_data->GetAttr(bp_ver,a_bp_ver_bp,bp);	
	if(!bp) return false;
	if(bp->GetAccessmode()>aplRW) {if(m_api->m_ModeInteractive)aplErrorMessage( APL_T("У Вас недостаточно прав чтобы сделать версию бизнес-процесса активной!"),bp); return false;}

	CaplInstance *lock=CheckMyLock(bp,false);
	if(GetLock(bp,false) && !lock) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Бизнес-процесс заблокирован другим пользователем !"),MB_OK|MB_ICONSTOP);return false;}
	
	CaplInstance *activeVer=0;
	m_data->GetAttr(bp,a_bp_act,activeVer);	
	//if(!activeVer) return false;
	if(activeVer==bp_ver && activeVer!=lock)
	{
		if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Версия уже активна!"));
		return false;
	}

	//проверка
	CString sId, sName, sDescr, sCode, sLabel;
	bool bCustomized=false, bOptional=false;
	CaplInstance* type= 0, *charact=0;
	aplExtent resources, subBP; //подпроцессы и ресурсы не волнуют
	aplExtent charactOld, charactNew; //характеристики надо проверить

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_id, sId);
	if(sId.IsEmpty())
	{
		m_api->m_bp_mgr.LoadBPInfo(bp_ver);
		m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_id, sId);
	}
	
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_name, sName);
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_descr, sDescr);
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_code, sCode);
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_label, sLabel);
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_type, type);
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_customized, bCustomized);
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_optional, bOptional);

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_elements, subBP);
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_res, resources);

	aplExtent oldGroups, newGroups;
	m_api->m_charact_mgr.FindAssociatedCharacteristic(activeVer, charactOld, oldGroups);
	m_api->m_charact_mgr.FindAssociatedCharacteristic(bp_ver, charactNew, newGroups);
	
	aplExtent extAccess;
	extAccess.Append(charactOld); extAccess.Append(charactNew);

	//отрезаем характеристики 
	for(i= 0; i<charactOld.GetSize(); i++)
	{
		charact= NULL;
		CaplInstance* charactActVer= NULL;
		m_api->m_data.GetAttr(charactOld[i], m_api->m_charact_mgr.a_apl_charact_val_ver_char_value, charact);
		if(charact && charact->GetAccessmode()<aplRO)
		{
			m_api->m_data.PutAttr(charact, m_api->m_charact_mgr.a_apl_charact_val_item, (CaplInstance*)NULL);
			m_api->m_data.PutAttr(charact, m_api->m_charact_mgr.a_apl_charact_val_base_item, bp);
		}
	}

	//проверка, активная ли
	for(i= 0; i<charactNew.GetSize(); i++)
	{
		charact= NULL;
		CaplInstance* charactActVer= NULL;
		m_api->m_data.GetAttr(charactNew[i], m_api->m_charact_mgr.a_apl_charact_val_ver_char_value, charact);
		if(charact)
		{
			m_api->m_data.GetAttr(charact, m_api->m_charact_mgr.a_apl_charact_val_act_ver, charactActVer);
			if(charactActVer && charactActVer!=charactNew[i])
			{
				m_api->m_charact_mgr.MakeCharValVersionActive(charactNew[i]);
			}
			//привязываем новые
			if(charact->GetAccessmode()<aplRO) 
				m_api->m_data.PutAttr(charact, m_api->m_charact_mgr.a_apl_charact_val_item, bp);
		}
	}
	
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_id, sId);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_name, sName);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_descr, sDescr);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_code, sCode);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_label, sLabel);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_type, type);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_customized, bCustomized);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_optional, bOptional);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_elements, subBP);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_res, resources);

	CaplInstance *tmp_inst;
	double tmp_rel;
	CString tmp_str;
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_org, tmp_inst);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_org, tmp_inst);
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_class, tmp_inst);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_class, tmp_inst);

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_percentage_of_otk, tmp_rel);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_percentage_of_otk, tmp_rel);

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_number_of_simultaneously_processed_parts, tmp_rel);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_number_of_simultaneously_processed_parts,tmp_rel );

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_t_sht, tmp_rel);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_t_sht, tmp_rel);

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_t_pz, tmp_rel);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_t_pz, tmp_rel);

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_coat, tmp_str);
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_coat, tmp_str);

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_directive,tmp_str );
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_directive,tmp_str );
	
	//установка активной версии
	m_api->m_data.PutAttr(bp, m_api->m_bp_mgr.a_bp_act, bp_ver);

	//создание объекта "Изменение"
	CaplInstance *change=m_data->CreateInstance(m_api->m_change_mgr.e_abpc);

	m_data->PutAttr(change, m_api->m_change_mgr.a_abpc_bp, bp);
	m_data->PutAttr(change, m_api->m_change_mgr.a_abpc_old_rev, activeVer);
	m_data->PutAttr(change, m_api->m_change_mgr.a_abpc_new_rev, bp_ver);
		
	CString buf;
	buf= m_api->m_change_mgr.GetBPCId(bp);
	if(buf!=_T(""))	m_data->PutAttr(change, m_api->m_change_mgr.a_chng_item_id, buf);
	CString basis;
	m_data->GetAttr(bp_ver,a_bp_ver_basis,basis);
	if(basis!=_T("")) m_data->PutAttr(change, m_api->m_change_mgr.a_chng_item_basis, basis);

	COleDateTime odt;
	CString s_dt;
	if(m_data->IsConnected()) m_data->NET_GetServerDateTime(odt);
	else odt=COleDateTime::GetCurrentTime();
	aplDate2String(odt,s_dt);
	m_data->PutAttr(change, m_api->m_change_mgr.a_chng_item_accept_date, s_dt);
	CaplInstance *person=m_api->m_appr_mgr.GetCurrentPerson();
	CaplInstance *user=m_data->GetCurrUser();
				
	if(user) m_data->PutAttr(change, m_api->m_change_mgr.a_chng_item_user, m_data->GetNameCurrUser());
	if(person) m_data->PutAttr(change, m_api->m_change_mgr.a_chng_item_autor, person);	

	CString sSubject=  APL_T("Изменение бизнес-процесса "), sContent=  APL_T("Поменялась активная версия бизнес-процесса");
			
	m_api->GetItemName(bp, buf);
	sSubject+=buf;

	CString version_guid;
	m_data->GetAttr(bp_ver,a_bp_ver_guid,version_guid);
	m_data->PutAttr(bp,a_bp_guid,version_guid);

	aplExtent sbscr_ext;
	m_api->m_message_mgr.GetItemsSubscribers(bp, sbscr_ext);
	aplExtent wo;
	wo.Add(bp);
	m_api->m_message_mgr.SendNotifyMessage(NULL, sbscr_ext,sSubject, sContent, wo);
	
	if(m_api->m_AutoSave) 
		m_api->m_data.NET_SaveChanges();
	return true;
}

bool CaplBPManager::DeleteBPRelation(CaplInstance *sub_bp,CaplInstance *base_bp)
{
	if(sub_bp==0) return false;
	if(sub_bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(sub_bp->GetType()==0) return false;
	if(base_bp==0) return false;
	if(base_bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(base_bp->GetType()==0) return false;
	
	if(base_bp->GetAccessmode()>aplRW) return false;
	if(!m_data->IsKindOf(base_bp,e_bp))
		if(!m_data->IsKindOf(base_bp,e_apl_bp_ver))
			return false;
	if(!m_data->IsKindOf(sub_bp,e_bp)) return false;

	CaplAggr aggr0;
	CaplInstance *inst;	

	if(m_data->IsKindOf(base_bp,e_bp))
	{
		if(m_bUseVersions)
		{
			base_bp=CheckMyLock(base_bp,true);
			if(!base_bp) return false;
		}
		else
			m_data->GetAttr(base_bp,a_bp_elements,aggr0);
	}
	if(m_data->IsKindOf(base_bp,e_apl_bp_ver))
		m_data->GetAttr(base_bp,a_bp_ver_elements,aggr0);

	bool found=false;
	for(int i=0;i<aggr0.GetSize();i++)
	{
		aggr0.GetByIndex(i,inst);
		if(inst==sub_bp)
		{
			aggr0.Remove(i);
			if(m_data->IsKindOf(base_bp,e_apl_bp_ver))
				m_data->PutAttr(base_bp,a_bp_ver_elements,aggr0);
			else
				m_data->PutAttr(base_bp,a_bp_elements,aggr0);
			found=true;
			break;
		}
	}
	if(!found) return false;
	if(m_AutoSave) 
		m_api->SaveChanges();
	return true;
	
}

bool CaplBPManager::DeleteBPInstRelation(CaplInstance *sub_bp_inst,CaplInstance *base_bp_inst)
{
	if(sub_bp_inst==0) return false;
	if(sub_bp_inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(sub_bp_inst->GetType()==0) return false;
	if(base_bp_inst==0) return false;
	if(base_bp_inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(base_bp_inst->GetType()==0) return false;
	if(base_bp_inst->GetAccessmode()>aplRW) return false;
	if(!m_data->IsKindOf(base_bp_inst,e_apl_bp_inst))
		return false;
	if(!m_data->IsKindOf(sub_bp_inst,e_apl_bp_inst))
		return false;

	CaplAggr aggr0;
	CaplInstance *inst;	
	m_data->GetAttr(base_bp_inst,a_bp_inst_elements,aggr0);
	bool found=false;
	for(int i=0;i<aggr0.GetSize();i++)
	{
		aggr0.GetByIndex(i,inst);
		if(inst==sub_bp_inst)
		{
			aggr0.Remove(i);
			m_data->PutAttr(base_bp_inst,a_bp_inst_elements,aggr0);
			found=true;
			break;
		}
	}
	if(!found) return false;
	if(m_AutoSave) 
		m_api->SaveChanges();
	return true;
}

bool CaplBPManager::GetAllSubBP(CaplInstance *bp,aplExtent &ext_out)
{
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(bp->GetAccessmode()>aplRW) return false;
	aplExtent ext;
	ext.Add(bp);
	GetAllSubBP(ext,ext_out);
	return true;
}

bool CaplBPManager::GetAllSubBP(aplExtent &bp_ext,aplExtent &ext_out)
{
	if(!m_data) return false;
	int i, j;
	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		for(i=0;i<bp_ext.GetSize();i++)
		{
			if(!bp_ext[i]) continue;
			if(bp_ext[i]->GetAccessmode()>aplRO) continue;
			if(!m_data->IsKindOf(bp_ext[i],e_bp))
				if(!m_data->IsKindOf(bp_ext[i],e_apl_bp_ver)) 
					continue;
			ld.AddQuery(0,bp_ext[i]);
		}
		if(ld.IsQueryNotEmpty())
		{

		int k=ld.AddQuery(_T('d'),0,0,a_bp_elements,true);
		int	u=ld.AddQuery(_T('d'),k,0,a_bp_lock,true);
			  ld.AddQuery(_T('d'),u,0,a_bp_ver_author,true);
			  ld.AddQuery(_T('d'),u,0,a_bp_ver_elements,true);
			  ld.AddQuery(_T('d'),0,0,a_bp_ver_elements,true);
			if(!ld.LoadEx()){
				if(apidata.GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS){
					if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
				}
			}
		}
	}

	aplExtent ext_rec; // Здесь будем накапливать элементы для ркурсивного вызова

	for(i=0;i<bp_ext.GetSize();i++)
	{
		if(!bp_ext[i]) continue;
		if(bp_ext[i]->GetAccessmode()>aplRO) continue;
		CaplAggr aggr,aggr_ver;
		if(m_data->IsKindOf(bp_ext[i],e_bp))
		{
			m_data->GetAttr(bp_ext[i],a_bp_elements,aggr);
			CaplInstance *lock=CheckMyLock(bp_ext[i],false);
			if(lock) m_data->GetAttr(lock,a_bp_ver_elements,aggr_ver);
		}
		else if(m_data->IsKindOf(bp_ext[i],e_apl_bp_ver)) 
		{
			m_data->GetAttr(bp_ext[i],a_bp_ver_elements,aggr_ver);
		}
		for(j=0;j<aggr.GetSize();j++)//добавление в экстент подпроцессов
		{
			CaplInstance *inst=0;
			aggr.GetByIndex(j,inst);
			if(inst) 
			{
				if(inst->GetAccessmode()<aplNO)
				{
					int n=ext_out.GetSize();
					ext_out.Add(inst);
					if(n!=ext_out.GetSize()) ext_rec.Add(inst); // Таким способом проверяем был ли элемент в ext_out
				}
			}
		}
		for(j=0;j<aggr_ver.GetSize();j++)//добавление в экстент подпроцессов 
		{								 //редактируемой версии, если уже не включены
			CaplInstance *inst=0;
			aggr_ver.GetByIndex(j,inst);
			if(inst) 
			{
				bool found=false;
				for(int k=0;k<ext_rec.GetSize();k++)
				{
					if(ext_rec[k]==inst) {found=true;break;}
				}
				if(!found)
				{
					int n=ext_out.GetSize();
					ext_out.Add(inst);
					if(n!=ext_out.GetSize()) ext_rec.Add(inst); // Таким способом проверяем был ли элемент в ext_out
				}
			}
		}
	}
	if(ext_rec.GetSize()) return GetAllSubBP(ext_rec,ext_out);
	return true;

}

//************************************************************************
//************************************************************************
bool CaplBPManager::GetAllSubBPInst(CaplInstance *inst, aplExtent &ext)
{
	CaplAggr aggr0;
	CaplInstance *inst1;
	int i;
	if(!m_data) return false;
	if(inst==0) return false;
	if(inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(inst->GetType()==0) return false;

	// ext.Clear(); не чистим - чтобы рекурсивно вызванные функции не гоняли 
	// данные туда-сюда, а добавляли в общий экстент
	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		i=ld.AddQuery(0,inst);
		ld.AddQuery(_T('d'), i, 0,a_bp_inst_elements, true);
		if(!ld.LoadEx()){
			if(apidata.GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS){
				if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
			}
		}
		
		m_data->GetAttr(inst,a_bp_inst_elements,aggr0);
		for(i=0;i<aggr0.GetSize();i++)
		{
			aggr0.GetByIndex(i,inst1);
			if(inst1==0) continue;
			if(inst1->GetType()==0) continue;
			if(ext.Find(inst1)>=0) continue;
			ext.Add(inst1);
			if(!GetAllSubBPInst(inst1,ext))return false;
		}	
	}
	return true;
}

/** Получает список экземпляров бизнесс-процессов для списка бизнес-процессов
	@param bp_ext список бизнес-процессов
	@param ext_out список найденных экземпляров бизнесс-процессов 
	@return true при удачном выполнении и false в случае ошибки */
bool CaplBPManager::GetBPInstForBP(aplExtent &bp_ext,aplExtent &ext_out)
{
	ext_out.Clear();
	if(!m_data) return false;
	int i,j;
	aplExtent ext;
	CaplInstance* inst;
	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		for(i=0;i<bp_ext.GetSize();i++){
			ld.AddQuery(0,bp_ext[i]);
		}
		if(ld.IsQueryNotEmpty())
		{
			ld.AddQuery(_T('r'), 0, e_apl_bp_inst,a_bp_inst_process, true);
			if(!ld.LoadEx(true,&ext))return false;
		}
		for(i=0;i<bp_ext.GetSize();i++){
			for(j=0;j<ext.GetSize();j++){
				if(m_data->IsKindOf(ext[j],e_apl_bp_inst)){
					m_data->GetAttr(ext[j],a_bp_inst_process,inst);
					if(inst==bp_ext[i]){
						ext_out.Add(ext[j]);
						ext.Remove(j);j--;
					}
				}else{
					ext.Remove(j);j--;
				}
			}
		}
	}else{
		CaplAttrValue tst_values[1];               
		for(i=0;i<bp_ext.GetSize();i++){
			tst_values[0].value.Set(bp_ext[i]); 
			tst_values[0].attr=a_bp_inst_process;      
			m_data->FindInstancesWithAttrValuesInLocalCache(e_apl_bp_inst,0,1,tst_values,ext,false,false,false);
			ext_out.Append(ext);
		}
	}
	return true;
}

/** Получает список экземпляров бизнесс-процессов для бизнес-процесса
	@param bp бизнес-процесс
	@param ext_out список найденных экземпляров бизнесс-процессов 
	@return true при удачном выполнении и false в случае ошибки */
bool CaplBPManager::GetBPInstForBP(CaplInstance* bp,aplExtent &ext_out)
{
	ext_out.Clear();
	if(m_data==0) return false;
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	
	int k;
	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		k=ld.AddQuery(0,bp);
		ld.AddQuery(_T('r'), k, e_apl_bp_inst,a_bp_inst_process, true);
		if(!ld.LoadEx()){
			if(apidata.GetLastAplError()!=APL_SOCK_OPERATION_IN_PROGRESS){
				if(m_api->m_ModeInteractive)AfxMessageBox(S::ErrorLoadDataMgr(),MB_OK|MB_ICONSTOP);
			}
		}
	}
	CaplAttrValue tst_values[1];               
	tst_values[0].value.Set(bp); 
	tst_values[0].attr=a_bp_inst_process;      

	m_data->FindInstancesWithAttrValuesInLocalCache(e_apl_bp_inst,0,1,tst_values,ext_out,false,false,false);
	return true;
}

//***********************************************************************
bool CaplBPManager::SetCustomizedRecursive(CaplInstance *bpTop, bool bCustomized)
{
	if(m_data==0) return false;
	if(bpTop==0) return false;
	if(bpTop==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bpTop->GetType()==0) return false;
	if(bpTop->GetAccessmode()>aplRW){AfxMessageBox(APL_T("Нет доступа!"),MB_OK|MB_ICONSTOP); return true;}
	aplExtent extSubBP;
	GetAllSubBP(bpTop,extSubBP);
	extSubBP.Add(bpTop);
	int i, n=0;
	for(i=0; i< extSubBP.GetSize(); i++)
	{
		CaplInstance *bp=extSubBP[i];
		if(bp->GetAccessmode()>aplRW) continue;
		bool bCurCustomized=false;
		m_data->GetAttr(bp,a_bp_customized, bCurCustomized);
		if(bCurCustomized!=bCustomized)
		{
			m_data->PutAttr(bp,a_bp_customized, bCustomized);
			n++;
		}
	}
	if(0==n)
	{
		if(m_api->m_ModeInteractive)
		{
			if(bCustomized )AfxMessageBox( APL_T("Все бизнес-процессы уже были индивидуальными."),MB_ICONINFORMATION);
			else AfxMessageBox( APL_T("Все бизнес-процессы уже были унифицированными."),MB_ICONINFORMATION);
		}
		return false;
	}

	m_api->SaveChanges();
	if(m_api->m_ModeInteractive)
	{
		CString buf;
		if(bCustomized )buf.Format(APL_T("%i бизнес-процессов сделаны индивидуальными"),n);
		else buf.Format(APL_T("%i бизнес-процессов сделаны унифицированными"),n);
		AfxMessageBox(buf,MB_ICONINFORMATION);
	}
	return true;
}
//***********************************************************************

CaplInstance *CaplBPManager::GetLock(CaplInstance *bp, bool bShowMessages)
{
	if(!m_bUseVersions) return 0;
	if(bp==0) return 0;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return 0;};
	if(bp->GetType()==0) return 0;
	if(bp->GetAccessmode()>aplRO) return 0;
	if(!m_data->IsKindOf(bp,e_bp)) 
		if(!m_data->IsKindOf(bp,e_apl_bp_ver))
			return 0;

	CaplInstance *lock=0,*user=0;
	CaplInstance *bp_ver_bp=0;
	if(m_data->IsKindOf(bp,e_bp))
	{
		bp_ver_bp=bp;
		m_data->GetAttr(bp,a_bp_lock,lock);
	}
	else if(m_data->IsKindOf(bp,e_apl_bp_ver))
	{
		m_data->GetAttr(bp,a_bp_ver_bp,bp_ver_bp);
		if(!bp_ver_bp) return 0;
		m_data->GetAttr(bp_ver_bp,a_bp_lock,lock);
	}else{
		return 0;
	}
	CString bp_id=_T("");
	m_data->GetAttr(bp_ver_bp,a_bp_id,bp_id);
	if(lock==0)
	{
		if(bShowMessages && m_api->m_ModeInteractive)AfxMessageBox( APL_T("Бизнес-процесс ")+bp_id+ APL_T(" не заблокирован !"),MB_OK|MB_ICONSTOP);
		return 0;
	}
		
	return lock;
	
}

bool CaplBPManager::LoadBPInstInfo(CaplInstance *bp_inst,bool bLoadSubBpInfo)
{
	if(bp_inst==0) return false;
	if(bp_inst==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp_inst->GetType()==0) return false;
	if(bp_inst->GetAccessmode()>aplRO) return false;
	
	aplExtent ext;
	ext.Add(bp_inst);
	return LoadBPInstInfo(ext,bLoadSubBpInfo);


}

bool CaplBPManager::LoadBPInstInfo(aplExtent &ext,bool bLoadSubBpInfo)
{
	if(!m_data) return false;
	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		int iLoad=0;
		for(int i=0;i<ext.GetSize();i++)
		{
			if(!ext[i]) continue;
			if(ext[i]->GetAccessmode()>aplRO) continue;
			if(ext[i]->GetId()==0) continue;
			if(ext[i]->GetType()==0) continue;

			iLoad++;
			ld.AddQuery(0,ext[i],true);
			if(iLoad==m_MaxItemsLoad || (i==(ext.Size-1) && iLoad>0))
			{
				iLoad=0;
				ld.AddQuery(_T('d'), 0, 0,a_bp_inst_process, true,true);
				ld.AddQuery(_T('d'), 0, 0,a_bp_inst_res, true,true);
				if(bLoadSubBpInfo)//Подпроцессы
					ld.AddQuery(_T('d'), 0, 0,a_bp_inst_elements, true,true);
				  
				ld.LoadEx();
			}
		}
	}
	return true;

}

bool CaplBPManager::IsBPChanged(CaplInstance *bp, CaplInstance *bp_ver)
{
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(bp->GetAccessmode()>aplRO) return true;
	if(bp_ver==0) return false;
	if(bp_ver==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp_ver->GetType()==0) return false;
	if(bp_ver->GetAccessmode()>aplRO) return true;
	if(!m_data->IsKindOf(bp,e_bp)) return true;
	if(!m_data->IsKindOf(bp_ver,e_apl_bp_ver)) return true;
	
	CString id_new,name_new,descr_new,code_new,label_new;
	CString id,name,descr,code,label;
	aplExtent ext_res,ext_res_new;
	aplExtent ext_elements,ext_elements_new;
	aplExtent ext_char_val_ver_old,ext_char_val_ver_new;
	CaplInstance *bp_type=0,*bp_type_new=0,*base=0,*act=0,*bp_ver_bp;
	bool bCustomized=false, bCustomizedNew=false;
	bool bOptional=false, bOptionalNew=false;
	int i,j;

	m_data->GetAttr(bp_ver,a_bp_ver_bp,bp_ver_bp);
	if(bp_ver_bp!=bp) return true;

	m_data->GetAttr(bp_ver,a_bp_ver_id,id_new);
	m_data->GetAttr(bp_ver,a_bp_ver_name,name_new);
	m_data->GetAttr(bp_ver,a_bp_ver_descr,descr_new);
	m_data->GetAttr(bp_ver,a_bp_ver_code,code_new);
	m_data->GetAttr(bp_ver,a_bp_ver_label,label_new);
	m_data->GetAttr(bp_ver,a_bp_ver_type,bp_type_new);
	m_data->GetAttr(bp_ver,a_bp_ver_customized, bCustomizedNew);
	m_data->GetAttr(bp_ver,a_bp_ver_optional, bOptionalNew);
	m_data->GetAttr(bp_ver,a_bp_ver_elements,ext_elements_new);
	m_data->GetAttr(bp_ver,a_bp_ver_res,ext_res_new);
	m_data->GetAttr(bp_ver,a_bp_ver_char_val_versions,ext_char_val_ver_new);
		
	m_data->GetAttr(bp,a_bp_id,id);
	m_data->GetAttr(bp,a_bp_name,name);
	m_data->GetAttr(bp,a_bp_descr,descr);
	m_data->GetAttr(bp,a_bp_code,code);
	m_data->GetAttr(bp,a_bp_label,label);
	m_data->GetAttr(bp,a_bp_type,bp_type);
	m_data->GetAttr(bp,a_bp_customized,bCustomized);
	m_data->GetAttr(bp,a_bp_optional,bOptional);
	m_data->GetAttr(bp,a_bp_elements,ext_elements);
	m_data->GetAttr(bp,a_bp_res,ext_res);
	m_data->GetAttr(bp,a_bp_act,act);
	aplExtent ext_char,ext_group;
	m_api->m_charact_mgr.FindAssociatedCharacteristic(bp,ext_char,ext_group,false,false,false);

	if(id!=id_new || name!=name_new || descr!=descr_new || bp_type!=bp_type_new 
		|| code!=code_new || label!=label_new || bCustomized!=bCustomizedNew || bOptional!=bOptionalNew) return true;


	CaplInstance *tmp_inst, *tmp_inst_new;
	double tmp_rel, tmp_rel_new;
	CString tmp_str,tmp_str_new;
	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_org, tmp_inst_new);
	m_api->m_data.GetAttr(bp, m_api->m_bp_mgr.a_bp_org, tmp_inst);
	if(tmp_inst!=tmp_inst_new)return true;

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_class, tmp_inst_new);
	m_api->m_data.GetAttr(bp, m_api->m_bp_mgr.a_bp_class, tmp_inst);
	if(tmp_inst!=tmp_inst_new)return true; //-V649

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_percentage_of_otk, tmp_rel_new);
	m_api->m_data.GetAttr(bp, m_api->m_bp_mgr.a_bp_percentage_of_otk, tmp_rel);
	if(tmp_rel_new!=tmp_rel)return true;

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_number_of_simultaneously_processed_parts, tmp_rel_new);
	m_api->m_data.GetAttr(bp, m_api->m_bp_mgr.a_bp_number_of_simultaneously_processed_parts,tmp_rel );
	if(tmp_rel_new!=tmp_rel)return true;

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_t_sht, tmp_rel_new);
	m_api->m_data.GetAttr(bp, m_api->m_bp_mgr.a_bp_t_sht, tmp_rel);
	if(tmp_rel_new!=tmp_rel)return true;

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_t_pz, tmp_rel_new);
	m_api->m_data.GetAttr(bp, m_api->m_bp_mgr.a_bp_t_pz, tmp_rel);
	if(tmp_rel_new!=tmp_rel)return true;


	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_coat, tmp_str_new);
	m_api->m_data.GetAttr(bp, m_api->m_bp_mgr.a_bp_coat, tmp_str);
	if(tmp_str_new!=tmp_str)return true;

	m_api->m_data.GetAttr(bp_ver, m_api->m_bp_mgr.a_bp_ver_directive,tmp_str_new );
	m_api->m_data.GetAttr(bp, m_api->m_bp_mgr.a_bp_directive,tmp_str );
	if(tmp_str_new!=tmp_str)return true;




	//сравнение по размеру списков ресурсов, вложенных процессов и характеристик 
	if(ext_res.GetSize()!=ext_res_new.GetSize()) return true; 
	if(ext_elements.GetSize()!=ext_elements_new.GetSize()) return true;
	if(ext_char_val_ver_new.GetSize()!=ext_char.GetSize()) return true;

	//ресурсы
	for(i=0;i<ext_res.GetSize();i++)
	{
		if(ext_res[i]!=ext_res_new[i]) return true;
	}
	//вложенные бп 
	for(i=0;i<ext_elements.GetSize();i++)
	{
		if(ext_elements[i]!=ext_elements_new[i]) return true;
	}
	//характеристики
	//m_api->m_charact_mgr.LoadCharacteristic(ext_char_val_ver_old);
	//m_api->m_charact_mgr.LoadCharacteristic(ext_char_val_ver_new);
	
	for(i=0;i<ext_char_val_ver_new.GetSize();i++)
	{
		bool bFound=false;
		if(ext_char_val_ver_new[i]->GetAccessmode()>aplRO) continue;
		CaplInstance *new_ver_char_val=0;
		m_data->GetAttr(ext_char_val_ver_new[i],m_api->m_charact_mgr.a_apl_charact_val_ver_char_value,new_ver_char_val);
		for(j=0;j<ext_char.GetSize();j++)
		{
			if(!ext_char[j]->GetType()) continue;
			if(ext_char[j]->GetAccessmode()>aplRO) continue;
			if(new_ver_char_val==ext_char[j]) 
			{
				bFound=true;
				bool is_changed;
				m_data->GetAttr(ext_char_val_ver_new[i],m_api->m_charact_mgr.a_apl_charact_val_ver_is_changed,is_changed);
				if(is_changed) return true;
			}
		}
		if(!bFound) return true;
	}
	return false;		

}

//*************************************************************
bool CaplBPManager::ShowBPChanges(CaplInstance *bp)
{
	if(bp==0) return false;
	if(bp==(CaplInstance*)-1) {if(m_api->m_ModeInteractive)AfxMessageBox( APL_T("Ошибка вызывающей программы! instance равен -1!"));return false;};
	if(bp->GetType()==0) return false;
	if(bp->GetAccessmode()>aplRO) return false;
	if(m_data==0) return false;
	if(e_bp==0) return false;

	if(m_data->IsConnected())
	{
		int i,j;
		CaplLoadData ld(m_data,DEF_SOURCE);
		CaplAttr *a_user=m_data->GetAttrDefinitionBN(_T("apl_user"),_T("name"));
		// ссылка
		i=ld.AddQuery(_T('b'), bp->GetId(), m_api->m_change_mgr.e_abpc,m_api->m_change_mgr.a_abpc_bp, true);
		j=ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_abpc_bp, true);
		  ld.AddQuery(_T('d'), j, 0,a_bp_act, true);
		  ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_chng_item_id, true);
		  ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_chng_item_basis, true);
		  ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_chng_item_dscr, true);
		  ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_chng_item_autor, true);
		j=ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_chng_item_attachment, true);
		  ld.AddQuery(_T('d'), j, 0,m_api->m_doc_mgr.a_apl_stored_document_file_name, true);
		  ld.AddQuery(_T('d'), j, 0,m_api->m_doc_mgr.a_apl_stored_document_source, true);
		  ld.AddQuery(_T('d'), j, 0,m_api->m_doc_mgr.a_apl_assigned_document_location_path, true);
		j=ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_chng_item_user, true);
		  ld.AddQuery(_T('d'), j, 0,a_user, true);
		j=ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_abpc_old_rev, true);
		  ld.AddQuery(j,_T('d'), i, 0,m_api->m_change_mgr.a_abpc_new_rev, true);
		  ld.AddQuery(_T('d'), j, 0,a_bp_ver_id, true);
		  ld.AddQuery(_T('d'), i, 0,m_api->m_change_mgr.a_chng_apply_date, true);
		  //ld.AddQuery(_T('d'), i, 0,a_apl_doc_change_date_s, true);
		ld.LoadEx();
	}

	CaplSetResourceHandle setres(module_inst);
	
	CDocChanges dlg;
	dlg.m_api= m_api;
	dlg.m_bp=bp;

	dlg.DoModal();
	return true;
}
//*************************************************************
CaplInstance* CaplBPManager::SelectBpType(CaplInstance *selected_bp_type,CaplInstance *selected_group)
{
	CaplSetResourceHandle setres(module_inst);
	CChoose_inst_dlg dlg;
	dlg.m_api= m_api;
	dlg.header= APL_T("Выбор типа бизнес-процесса");
	dlg.e_group=0;//e_dt_group;
	dlg.a_group_id=0;//a_dt_group_id;
	dlg.a_group_name=0;//a_dt_group_name;
	dlg.a_group_description=0;//a_dt_group_descr;
	dlg.a_group_content=0;//a_dt_group_content;
	dlg.a_group_parent=0;//a_dt_group_par;
	dlg.e_elem=e_bp_type;

	dlg.selected_element=selected_bp_type;
	dlg.selected_group=0;//selected_group;

	dlg.tmp.header= APL_T("Тип бизнес-процесса");
	dlg.tmp.function_type=0;
	dlg.tmp.attr=a_bp_type_name;
	dlg.tmp.second_attr=0;
	dlg.tmp.width=80;
	dlg.elements.Add(dlg.tmp);
/*
	if(m_sel_doc_types_names.GetSize()>0)
	{
		dlg.m_attr_for_def=a_dt_pdt;
		dlg.m_default_names=&m_sel_doc_types_names;
	}
*/
	int ret=dlg.DoModal();
	if(ret==IDOK)
		return dlg.GetChosenElement();

	return 0;
}

CaplInstance* CaplBPManager::GetBpTypeByName(LPCTSTR lpctstrName)
{
	if(!m_api)
		return NULL;
	if(!m_api->m_data.IsConnected())
		return NULL;

	aplExtent ext;
	CString buf;
	CString sEtalon(lpctstrName);	//Добавлено из-за глюков в работе функции CompareNoCase
	sEtalon.MakeLower();			//Добавлено из-за глюков в работе функции CompareNoCase
	m_api->m_data.GetEntityExtent(e_bp_type, ext);
	for(int i=0; i<ext.Size; i++)
	{
		m_api->m_data.GetAttr(ext[i], a_bp_type_name, buf);
		buf.MakeLower();//Добавлено из-за глюков в работе функции CompareNoCase
		if(buf==sEtalon) return ext[i];
	}
	return NULL;
}

//	функции для работы с расцеховкой

bool CaplBPManager::GetRascString(CaplInstance* ciRootBP,CaplInstance* ciOffsetChar,
								  CString& csDepotSep,CString& csGrpSep,bool bReadGrps,
								  CString& csOutRasc)
{
	CaplInstance*	cit			=NULL;

	CaplInstance*	ciCV		=NULL;

	aplExtent		aeSupBPs;
	
	CString			cst1=_T(""),cst2=_T(""),cst3=_T("");
	CString			csID;

	double dval;
	int i=0;

	csOutRasc=_T("");
	if(NULL==ciRootBP)
		return true;

	//	получаем все субпроцессы
	m_api->m_data.GetAttr(ciRootBP,a_bp_elements,aeSupBPs);

	for(i=0;i<aeSupBPs.GetSize();i++)
	{
		cit=aeSupBPs.GetAt(i);
		//	получаем наименование для субпроцесса - пойдет в расцеховку
		m_api->m_data.GetAttr(cit,a_bp_name,cst1);
		//	получаем обозначение для субпроцесса
		m_api->m_data.GetAttr(cit,a_bp_id,csID);
		//	если последняя буква в обозначении - П или Т - цеха покрытия или 
		//	термообработки - в расцеховку не входят. пропускаем
		if((csID.GetLength()>0 && (csID.Right(1)==APL_T("П")) || csID.Right(1)==APL_T("Т")))
			continue;
		//	если надо читать группы опережения
		if(true==bReadGrps)
		{
			//	если задана характеристика для групп
			if(NULL!=ciOffsetChar)
			{
				//	получаем значение характеристики для субпроцесса
				ciCV=GetInstCharVal(cit,ciOffsetChar);
				if(NULL!=ciCV)
				{
					//	читаем значение - должно быть a_apl_charact_val_meas_val
					m_api->m_data.GetAttr(ciCV,m_api->m_charact_mgr.a_apl_charact_val_meas_val,
										  dval);
					cst3=_T("");
					if(0!=dval)
						cst3.Format(_T("%g"),dval);
				}
			}
		}
		cst2+=cst1;
		if(true==bReadGrps && cst3!=_T(""))
		{
			cst2+=csGrpSep;
			cst2+=cst3;
		}
		cst3=_T("");
		cst2+=csDepotSep;
	}
	cst2.Delete(cst2.GetLength()-1,1);

	csOutRasc=cst2;

	return true;
}

bool CaplBPManager::DeleteRasc(CaplInstance* ciRootBPRel,bool bDelRoot)
{
	aplExtent		aeInstsForDel;

	CaplInstance*	cit1		=NULL;

	int				i,is;

	if(NULL==ciRootBPRel)
		return true;

	GetRascInsts(ciRootBPRel,aeInstsForDel,bDelRoot);

	is=aeInstsForDel.GetSize();
	for(i=0;i<is;i++)
	{
		cit1=aeInstsForDel.GetAt(i);
		if(NULL==cit1)
			continue;
		m_api->m_data.DeleteInstance(cit1,false);
	}

	return true;
}

bool CaplBPManager::ValidateRasc(CString& csInRasc,CString& csDepotSep,CString& csGrpSep)
{
	CString			csNumbers=_T("0123456789");
	CString			csValidSymbols;

	CString			cst;

	CStringArray	csaDepots;

	aplExtent		aeOrgs;

	CaplInstance*	cit1		=NULL;

	int			i,is;

	if(_T("")==csInRasc)
		return true;

	//	проверяем на не валидные символы

	cst=csInRasc;

	//	создаем список валидных символов
	csValidSymbols+=csNumbers;
	csValidSymbols+=csDepotSep;
	csValidSymbols+=csGrpSep;

	is=csValidSymbols.GetLength();
	for(i=0;i<is;i++)
		cst.Remove(csValidSymbols[i]);

	//	присутствуют не валидные символы
	if(_T("")!=cst)
		return false;

	//	проверяем содержимое - цеха должны существовать
	ParseRasc(csInRasc,csDepotSep,csGrpSep,&csaDepots,NULL);

	is=csaDepots.GetSize();
	for(i=0;i<is;i++)
	{
		cit1=NULL;
		cst=csaDepots.GetAt(i);
		//	ищем организацию
		cit1=m_api->m_appr_mgr.FindOrganizationById(cst);
		//	если не нашли - выходим
		if(NULL==cit1)
			return false;
	}

	return true;
}

bool CaplBPManager::CreateRasc(CaplInstance* ciInPdf,CaplInstance* ciBPRascType,
							   CaplInstance* ciBPDepotType,CaplInstance* ciShopChar,
							   CaplInstance* ciOffsetChar,CString& csInRasc,
							   CString& csDepotSep,CString& csGrpSep,
							   aplExtent& aeOutRasc)
{
	CaplInstance*		ciPrd		=NULL;

	CaplInstance*		ciRootBP	=NULL;
	CaplInstance*		ciRootBPRev	=NULL;

	CaplInstance*		ciChildBP	=NULL;

	aplExtent			aeChilds;

	CString				csPdfId,csPrdId;
	CString				csRootBPId;

	CStringArray		csaDepots,csaGrps;

	int					i,is;


	if(NULL==ciInPdf)
		return false;
	if(NULL==ciBPRascType)
		return false;
	if(NULL==ciBPDepotType)
		return false;
	if(NULL==ciShopChar)
		return false;
	if(NULL==ciOffsetChar)
		return false;
	if(_T("")==csInRasc)
		return false;

	if(false==ValidateRasc(csInRasc,csDepotSep,csGrpSep))
		return false;

	m_api->m_data.GetAttr(ciInPdf,m_api->m_prd_mgr.a_pdf_prd,ciPrd);
	m_api->m_data.GetAttr(ciPrd,m_api->m_prd_mgr.a_prd_id,csPrdId);
	m_api->m_data.GetAttr(ciInPdf,m_api->m_prd_mgr.a_pdf_id,csPdfId);

	csRootBPId=csPrdId;
	if(_T("")!=csPdfId)
	{
		csRootBPId+=_T("-");
		csRootBPId+=csPdfId;
	}

	CreateRootRascBP(ciInPdf,csRootBPId,ciBPRascType,ciRootBP,ciRootBPRev,aeOutRasc);

	ParseRasc(csInRasc,csDepotSep,csGrpSep,&csaDepots,&csaGrps);

	is=csaDepots.GetSize();
	for(i=0;i<is;i++)
	{
		ciChildBP=NULL;

		CreateRascItem(ciRootBP,csPrdId,i+1,csaDepots[i],csaGrps[i],ciBPDepotType,
			ciShopChar,ciOffsetChar,ciChildBP,aeOutRasc);
		aeChilds.Add(ciChildBP);
	}

	m_api->m_data.PutAttr(ciRootBP,a_bp_elements,aeChilds);
	m_api->m_data.PutAttr(ciRootBPRev,a_bp_ver_elements,aeChilds);

	return true;
}

void CaplBPManager::ParseRasc(CString& csInRasc,CString& csDepotSep,CString& csGrpSep,
							  CStringArray* csapOutDepots,CStringArray* csapOutGrps)
{
	CString		csAll,csPart,csDep,csGrp;

	int			iLen4Del=-1;

	csAll=csInRasc;

	do 
	{
		csPart=_T("");csDep=_T("");csGrp=_T("");
		
		//	получаем цех (и группу, если есть)
		csPart=csAll.SpanExcluding(csDepotSep); //-V519
		//	получаем только цех
		csDep=csPart.SpanExcluding(csGrpSep); //-V519

		//	получаем группу
		if(csDep.GetLength()<csPart.GetLength())
			csGrp=csPart.Right(csPart.GetLength()-csDep.GetLength()-1);

		if(NULL!=csapOutDepots)
			csapOutDepots->Add(csDep);

		if(NULL!=csapOutGrps)
			csapOutGrps->Add(csGrp);

		iLen4Del=csPart.GetLength();
		if(csAll.GetLength()>=csPart.GetLength()+1)
			iLen4Del++;
		csAll.Delete(0,iLen4Del);
	} 
	while(_T("")!=csAll);
}

void CaplBPManager::GetRascInsts(CaplInstance* ciRootBPRel,aplExtent& aeOutInsts,
								 bool bIncludeRoot)
{
	aplExtent		aeBPs,aeBPRevs,aeCVs,aeCVRevs;
	aplExtent		aeAllBPRevs;

	aplExtent		aet;

	CaplInstance*	ciRootBP	=NULL;

	CaplInstance*	cit1		=NULL;
	CaplInstance*	cit2		=NULL;

	int				i,is;

	if(NULL==ciRootBPRel)
		return;

	//	получаем корневой бизнес-процесс
	m_api->m_data.GetAttr(ciRootBPRel,a_bp_ref_process,ciRootBP);
	if(true==bIncludeRoot)
		aeOutInsts.Add(ciRootBPRel);
	if(NULL!=ciRootBP)
	{
		//	получаем суб-процессы
		m_api->m_data.GetAttr(ciRootBP,a_bp_elements,aeBPs);
		if(true==bIncludeRoot)
			aeBPs.Add(ciRootBP);
	}

	//	получаем все версии бизнес-процессов
	m_api->m_data.GetEntityExtent(e_apl_bp_ver,aeAllBPRevs);
	CSortClass::SortExtentById(aeBPs);
	is=aeAllBPRevs.GetSize();
	for(i=0;i<is;i++)
	{
		cit2=NULL;
		//	версия бизнес-процесса
		cit1=aeAllBPRevs.GetAt(i);
		if(NULL==cit1)
			continue;
		//	бизнес-процесс
		m_api->m_data.GetAttr(cit1,a_bp_ver_bp,cit2);
		if(NULL!=cit2)
		{
			//	если бизнес-процесс найден в нашем массиве - добавляем версию
			if(-1!=aplQFindInstIdInExtent(aeBPs,cit2->GetId()))
				aeBPRevs.Add(cit1);
		}
	}

	//	получаем версии значений характеристик
	is=aeBPRevs.GetSize();
	for(i=0;i<is;i++)
	{
		cit1=aeBPRevs.GetAt(i);
		if(NULL==cit1)
			continue;
		m_api->m_data.GetAttr(cit1,a_bp_ver_char_val_versions,aet);
		aeCVRevs.Append(aet);
		aet.Clear();
	}

	//	получаем значения характеристик
	is=aeCVRevs.GetSize();
	for(i=0;i<is;i++)
	{
		cit1=aeCVRevs.GetAt(i);
		m_api->m_data.GetAttr(cit1,m_api->m_charact_mgr.a_apl_charact_val_ver_char_value,cit2);
		if(NULL==cit2)
			continue;
		aeCVs.Add(cit2);
	}

	aeOutInsts.Append(aeBPs);
	aeOutInsts.Append(aeBPRevs);
	aeOutInsts.Append(aeCVRevs);
	aeOutInsts.Append(aeCVs);
}

CaplInstance* CaplBPManager::GetInstCharVal(CaplInstance* ciInst,CaplInstance* ciChar)
{
	aplExtent		aeCVs;

	CaplInstance*	cit1		=NULL;
	CaplInstance*	cit2		=NULL;
	CaplInstance*	cit3		=NULL;
	int				iInCvsSize	=0,i;

	if(NULL==ciInst || NULL==ciChar)
		return NULL;

	m_api->m_data.GetEntityExtent(m_api->m_charact_mgr.e_apl_charact_value,aeCVs);

	iInCvsSize=aeCVs.GetSize();
	if(iInCvsSize==0)
		return NULL;

	for(i=0;i<iInCvsSize;i++)
	{
		cit1=aeCVs.GetAt(i);
		if(NULL!=cit1)
		{
			if(cit1->GetAccessmode()==aplNO)
				continue;
			m_api->m_data.GetAttr(cit1,m_api->m_charact_mgr.a_apl_charact_val_item,cit2);
			if(cit2==ciInst)
			{
				m_api->m_data.GetAttr(cit1,m_api->m_charact_mgr.a_apl_charact_val_charact,cit3);
				if(cit3==ciChar)
					return cit1;
			}
		}
	}

	return NULL;	
}

void CaplBPManager::CreateRootRascBP(CaplInstance* ciInItem,CString& csBPId,
									 CaplInstance* ciRootBPType,CaplInstance*& ciOutRootBP,
									 CaplInstance*& ciOutRootBPRev,aplExtent& aeOutRasc)
{
	CaplInstance*	cit				=NULL;

	CreateRascBP(NULL,ciRootBPType,ciOutRootBP,ciOutRootBPRev);

	cit=m_api->m_data.CreateInstance(e_bp_ref);
	m_api->m_data.PutAttr(cit,a_bp_ref_process,ciOutRootBP);
	m_api->m_data.PutAttr(cit,a_bp_ref_item,ciInItem);

	m_api->m_data.PutAttr(ciOutRootBP,a_bp_id,csBPId);
	m_api->m_data.PutAttr(ciOutRootBP,a_bp_name, APL_T("Расцеховка"));

	m_api->m_data.GetAttr(ciOutRootBP,a_bp_act,cit);
	m_api->m_data.PutAttr(cit,a_bp_ver_id,csBPId);
	m_api->m_data.PutAttr(cit,a_bp_ver_name, APL_T("Расцеховка"));

	aeOutRasc.Add(ciOutRootBP);
	aeOutRasc.Add(ciOutRootBPRev);
}

void CaplBPManager::CreateRascItem(CaplInstance* ciInParentBP,CString& csBPIdPrefix,
								   int iNum,CString& csDepot,CString& csGrp,
								   CaplInstance* ciDepotBPType,CaplInstance* ciShopChar,
								   CaplInstance* ciOffsetChar,CaplInstance*& ciOutDepotBP,
								   aplExtent& aeOutRasc)
{
	CaplInstance*	ciBPRev		=NULL;

	CaplInstance*	ciCV		=NULL;
	CaplInstance*	ciCVRev		=NULL;

	CaplInstance*	ciDepot		=NULL;

	aplExtent		aet;

	CString			csBPId;

	double			dGrp		=-1;

	csBPId.Format(_T("%s_%d"),csBPIdPrefix,iNum);
	if(_T("")!=csGrp)
		dGrp=__atof(csGrp);
	ciDepot=m_api->m_appr_mgr.FindOrganizationById(csDepot);


	CreateRascBP(ciInParentBP,ciDepotBPType,ciOutDepotBP,ciBPRev);

	m_api->m_data.PutAttr(ciOutDepotBP,a_bp_id,csBPId);
	m_api->m_data.PutAttr(ciOutDepotBP,a_bp_name,csDepot);

	m_api->m_data.PutAttr(ciBPRev,a_bp_ver_id,csBPId);
	m_api->m_data.PutAttr(ciBPRev,a_bp_ver_name,csDepot);

	aeOutRasc.Add(ciOutDepotBP);
	aeOutRasc.Add(ciBPRev);
	

	CreateRascRefCV(ciOutDepotBP,ciShopChar,ciDepot,ciCV,ciCVRev);
	aeOutRasc.Add(ciCV);
	aeOutRasc.Add(ciCVRev);

	aet.Add(ciCVRev);

	if(-1!=dGrp)
	{
		CreateRascMeasuredCV(ciOutDepotBP,ciOffsetChar,dGrp,ciCV,ciCVRev);
		aeOutRasc.Add(ciCV);
		aeOutRasc.Add(ciCVRev);

		aet.Add(ciCVRev);
	}

	m_api->m_data.PutAttr(ciBPRev,m_api->m_bp_mgr.a_bp_ver_char_val_versions,aet);
}

void CaplBPManager::CreateRascBP(CaplInstance* ciInParentBP,CaplInstance* ciBPType,
								 CaplInstance*& ciOutBP,CaplInstance*& ciOutBPRev)
{
	ciOutBP=m_api->m_data.CreateInstance(e_bp);
	ciOutBPRev=m_api->m_data.CreateInstance(e_apl_bp_ver);

	m_api->m_data.PutAttr(ciOutBP,a_bp_state,_T("working"));
	m_api->m_data.PutAttr(ciOutBP,a_bp_type,ciBPType);
	m_api->m_data.PutAttr(ciOutBP,a_bp_parent,ciInParentBP);
	
	m_api->m_data.PutAttr(ciOutBPRev,a_bp_ver_num,_T("0"));
	m_api->m_data.PutAttr(ciOutBPRev,a_bp_ver_type,ciBPType);
	m_api->m_data.PutAttr(ciOutBPRev,a_bp_ver_author,m_api->m_data.GetCurrUser());
	COleDateTime dt=COleDateTime::GetCurrentTime();
	CString date_time; aplDate2String(dt,date_time);
	m_api->m_data.PutAttr(ciOutBPRev,a_bp_ver_start,date_time);
	m_api->m_data.PutAttr(ciOutBPRev,a_bp_ver_end,date_time);
	
	m_api->m_data.PutAttr(ciOutBPRev,a_bp_ver_bp,ciOutBP);
	m_api->m_data.PutAttr(ciOutBP,a_bp_act,ciOutBPRev);
}

void CaplBPManager::CreateRascRefCV(CaplInstance* ciItem,CaplInstance* ciChar,
									CaplInstance* ciVal,CaplInstance*& ciOutCV,
									CaplInstance*& ciOutCVRev)
{
	ciOutCV=m_api->m_data.CreateInstance(m_api->m_charact_mgr.e_apl_reference_value);

	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_item,ciItem);
	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_type,(CaplInstance*)NULL);
	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_charact,ciChar);	
	ciOutCVRev=m_api->m_charact_mgr.CreateCharValVersion(ciOutCV,_T("0"));

	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_reference_val,ciVal);
	m_api->m_data.PutAttr(ciOutCVRev,m_api->m_charact_mgr.a_apl_reference_val_ver_val,ciVal);
}

void CaplBPManager::CreateRascMeasuredCV(CaplInstance* ciItem,CaplInstance* ciChar,
										 double dVal,CaplInstance*& ciOutCV,
										 CaplInstance*& ciOutCVRev)
{
	ciOutCV=m_api->m_data.CreateInstance(m_api->m_charact_mgr.e_meas_value);

	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_item,ciItem);
	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_type,(CaplInstance*)NULL);
	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_charact,ciChar);

	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_meas_val,dVal);
	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_meas_max,0);
	m_api->m_data.PutAttr(ciOutCV,m_api->m_charact_mgr.a_apl_charact_val_meas_min,0);

	ciOutCVRev=m_api->m_charact_mgr.CreateCharValVersion(ciOutCV,_T("0"));
}

CaplInstance* CaplBPManager::FindBPInstById(const TCHAR *id, bool bAutoLoadInfo /* = true */)
{
	if (id==0)return 0;
	if (m_data==0)return 0;
	if(e_apl_bp_inst==0) return 0;

	aplExtent ext;
	CaplAttrValue tst_value;

	tst_value.value.Set(id);
	tst_value.attr=a_bp_inst_id;
	m_data->NET_FindInstancesWithAttrValues(e_apl_bp_inst,1,&tst_value,ext,false);
	if(ext.Size==0) return NULL;

	if(bAutoLoadInfo)
		LoadBPInstInfo(ext);

	return ext[0];
}