#include "StdAfx.h"
#include "CaplFaultMgr.h"
#include "refusalfilterdlg.h"
#include "RefusalPropertyDlg.h"
#include <aplWorkFlowManager.h>


typedef pair <CString, long> Str_Long_Pair;
typedef pair <CString, CString> Str_Str_Pair;

extern HINSTANCE hDllInst;

static const std::string base64_chars = 
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

#define APL_STR_LOGBOOK_PARENT_CONFIGURATION_COUNT	APL_NO_T("LOGBOOK\\PARENT_CONFIGURATIONS_COUNT")
#define APL_STR_LOGBOOK_PARENT_CONFIGURATION		APL_NO_T("LOGBOOK\\PARENT_CONFIGURATION")

static inline bool is_base64(unsigned char c)
{
	return (isalnum(c) || (c == _T('+')) || (c == _T('/')));
}


CaplFaultMgr::CaplFaultMgr()
{
	m_api = 0;
	m_ExplMgr = 0;
	m_pStatus = 0;
	m_nItemsPerOneLoad = 1500;
	m_bReadOnly=false;
}

CaplFaultMgr::~CaplFaultMgr(void)
{
	ClearConditions();
}

bool CaplFaultMgr::Attach( CaplAPI *api)
{
	if(0==api) return false;
	m_api = api;
	m_ExplMgr = api->m_expl_mgr;

	m_bReadOnly=false;

	LoadClassifiers();
	ClearConditions();
	InitConditions();

	return (api && m_ExplMgr);
}

bool CaplFaultMgr::LoadClassifiers()
{
	aplExtent aeSystems;
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_TYPE_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_MANIF_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(CULPRIT_DEDUCTION_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(TEST_DEDUCTION_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_CONDITIONS_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_CONSEQ_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_REASON_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_METHOD_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_DOF_CLASSIFIER_LVL, true));
	aeSystems.Add(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_STAGE_CLASSIFIER_LVL, true));
	m_api->LoadExtentInfo(aeSystems);
	return true;
}

bool CaplFaultMgr::LoadRefusalCharacts(aplExtent &aeRefusal)
{
	if(!IsReadyForWork()) return false;
	if(!aeRefusal.Size) return false;

	long dID = aplStartWaitDlg(APL_T("Загрузка характеристик..."));

	int nCount = 0;
	aplExtent aeCharact, aeTmp;
	
	// загружаем только нужное
	for(int i=0; i<aeRefusal.Size; i++) 
	{
		if(!aeRefusal[i]->GetType()) continue;

		nCount++;
		aeTmp.Add(aeRefusal[i]);

		if(nCount==m_nItemsPerOneLoad || i==(aeRefusal.Size-1))
		{
			aeCharact.Clear();
			m_api->m_charact_mgr.FindAssociatedCharacteristic(aeTmp, aeCharact);
			aeTmp.Clear();
		}
	}

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::LoadRefusalDocuments(aplExtent &aeRefusal)
{
	if(!IsReadyForWork()) return false;
	if(!aeRefusal.Size) return false;

	long dID = aplStartWaitDlg(APL_T("Загрузка документов..."));

	int nCount = 0;
	aplExtent aeDocs, aeTmp, aeRel;

	// загружаем только нужное
	for(int i=0; i<aeRefusal.Size; i++) 
	{
		if(!aeRefusal[i]->GetType()) continue;

		nCount++;
		aeTmp.Add(aeRefusal[i]);

		if(nCount==m_nItemsPerOneLoad || i==(aeRefusal.Size-1))
		{			
			m_api->m_doc_mgr.FindAssociatedDocuments(aeTmp, aeDocs, aeRel);
			m_api->m_doc_mgr.LoadDocInfo(aeTmp);
			aeTmp.Clear();			
		}
	}

	aplEndWaitDlg(dID);
	return true;
}
bool CaplFaultMgr::LoadRefusalInfo(CaplInstance *Refusal)
{
	if(0==Refusal) return false;
	if(Refusal->IsDeleted()) return false;
	aplExtent ext; 
	ext.Add(Refusal);
	return LoadRefusalInfo(ext);
}

bool CaplFaultMgr::LoadRefusalInfo( aplExtent &aeRefusal )
{
	if(!IsReadyForWork()) return false;
	if(!aeRefusal.Size) return false;

	long dID = aplStartWaitDlg(APL_T("Загрузка атрибутов неисправностей..."));

	int nCount = 0;
	CaplLoadData ld(&m_api->m_data, DEF_SOURCE);

	// загружаем только нужное
	for(int i=0; i<aeRefusal.Size; i++) 
	{
		if(!aeRefusal[i]->GetType()) continue;

		nCount++;
		ld.AddQuery(0, aeRefusal[i], true);

		if(nCount==m_nItemsPerOneLoad || i==(aeRefusal.Size-1))
		{
			// борт (основное изделие)
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_planer, true, true);

			// информация о детали
			int m1 = ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_part, true, true);
			int m2 = ld.AddQuery(_T('d'), m1, 0, m_api->m_prd_inst_mgr.a_prd_inst_pdf, true, true);
			ld.AddQuery(_T('d'), m2, 0, m_api->m_prd_mgr.a_pdf_prd, true, true);
			int m3 = ld.AddQuery(_T('d'), m1, 0, m_api->m_prd_mgr.a_pdf_prd, true, true);	

			// информация о блоке
			int p1 = ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_item, true, true);
			int p2 = ld.AddQuery(_T('d'), p1, 0, m_api->m_prd_inst_mgr.a_prd_inst_pdf, true, true);
			ld.AddQuery(_T('d'), p2, 0, m_api->m_prd_mgr.a_pdf_prd, true, true);

			// информация о системе, в которой была неисправность
			int o1 = ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_system, true, true);
			int o2 = ld.AddQuery(_T('d'), o1, 0, m_api->m_prd_inst_mgr.a_prd_inst_pdf, true, true);
			ld.AddQuery(_T('d'), o2, 0, m_api->m_prd_mgr.a_pdf_prd, true, true);

			// информация о борте
			int b1 = ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_planer, true, true);
			int b2 = ld.AddQuery(_T('d'), b1, 0, m_api->m_prd_inst_mgr.a_prd_inst_pdf, true, true);
			ld.AddQuery(_T('d'), b2, 0, m_api->m_prd_mgr.a_pdf_prd, true, true);
			
			// информация об организациях
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_org, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_sector, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_research_lab, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_research_sector, true, true);

			// информация из справочников
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_type, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_manifestation, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_dof, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_faultreason, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_type, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_stage, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_conditions, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_method, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_consequences, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_culprit, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_research_lab, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_research_sector, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_test_deduction, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_culprit_deduction, true, true);	

			// партии
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_item_lot, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_part_lot, true, true);

			// документы неисправности
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_document_obj, true, true);
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_research_act_obj, true, true);

			// файлы неисправности
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal, m_ExplMgr->a_apl_refusal_files, true, true);

			ld.LoadEx(true, NULL);
			nCount = 0;
		}
	}	

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::IsReadyForWork()
{
	if(!m_api) return false;
	if(!m_ExplMgr) return false;
	if(!m_api->m_data.IsConnected()) return false;
	
	return true;
}

CaplInstance* CaplFaultMgr::CreateRefusal(CaplInstance *ciParentRefusal, aplExtent &aeUpdatedRefusal, aplExtent *ext_doc, CaplInstance *src_refusal, CaplInstance *prd_inst)
{
	CaplInstance *ciNewRefusal = 0;

	CaplSetResourceHandle setres(hDllInst);

	CRefusalPropertyDlg dlg(m_api, this);
	dlg.m_ciParentRef = ciParentRefusal;
	dlg.m_ciSourceRefusal = src_refusal;

	if(0!=prd_inst)
	{
		if(m_api->m_data.IsKindOf(prd_inst,m_api->m_prd_inst_mgr.e_prd_inst))
			dlg.m_ciMainPdf = prd_inst;
	}
	
	if(0!=src_refusal) {aplExtent ext; ext.Add(src_refusal); LoadRefusalInfo(ext);}
	if(0!=ext_doc)dlg.m_extDocs4Add=*ext_doc;

	if(dlg.DoModal() == IDOK)
	{
		ciNewRefusal = dlg.m_ciRef;
		aeUpdatedRefusal.Append(dlg.m_aeRefusalToUpdate);
	}

	return ciNewRefusal;
}


bool CaplFaultMgr::ShowRefusalProperty( CaplInstance *ciRefusal, aplExtent &aeUpdatedRefusal )
{
	if(!IsReadyForWork()) return false;
	if(!ciRefusal) return false;

	CaplInstance *old_planer;
	m_api->m_data.GetAttr(ciRefusal,m_ExplMgr->a_apl_refusal_planer,old_planer);

	CaplSetResourceHandle setres(hDllInst);

	CRefusalPropertyDlg dlg(m_api, this);
	dlg.m_ciRef = ciRefusal;
	
	if(dlg.DoModal() == IDOK) 
	{
		aeUpdatedRefusal.Append(dlg.m_aeRefusalToUpdate);
		UpdateRefusalInfoInWF(ciRefusal,old_planer);
		return true;
	}
	return false;
}

bool CaplFaultMgr::UpdateRefusalInfoInWF(CaplInstance *ciRefusal, CaplInstance *old_planer)
{
	if(!m_api->m_options_mgr.CheckInstallCode(APL_NO_T("Созвездие"))) return true;

	if(0==m_api->m_wf_mgr) return false;
	if(0==m_ExplMgr) return false;
	if(dynamic_cast<CaplWorkFlowManager*>(m_api->m_wf_mgr)==NULL)return false;
	
	// Добавляем основное изделие в процесс
	CaplInstance *new_planer;
	m_api->m_data.GetAttr(ciRefusal,m_ExplMgr->a_apl_refusal_planer,new_planer);
	
	if(new_planer==old_planer || 0==new_planer ) return true;

	CaplWorkFlowManager *wf_mgr=(CaplWorkFlowManager*)m_api->m_wf_mgr;

	CaplInstance *inst,*inst1;
	aplExtent ext_proc,ext_wo;
	wf_mgr->FindProcessContained(ciRefusal,ext_proc);
	if(ext_proc.GetSize()<=0) return true;
	
	wf_mgr->LoadProcessInfo(ext_proc);

	bool bNeedSave=false;
	for(int i=0;i<ext_proc.Size;i++)
	{
		CaplInstance *process=ext_proc[i];
		m_api->m_data.GetAttr(process, wf_mgr->a_proc_wo, ext_wo);
		m_api->LoadExtentInfo(ext_wo);

		int index4Delete=-1;
		bool bDeleteOld=true;
		bool bAdd=true;

		for(int j=0; j<ext_wo.GetSize(); j++)
		{
			m_api->m_data.GetAttr(ext_wo[j], wf_mgr->a_wo_object, inst);
			if(inst)
			{
				if(inst==new_planer) {bAdd=false; continue;}
				if(inst==old_planer) {index4Delete=j;continue;}
				if(inst!=ciRefusal && m_api->m_data.IsKindOf(inst,m_ExplMgr->e_apl_refusal))
				{
					LoadRefusalInfo(inst);
					m_api->m_data.GetAttr(inst,m_ExplMgr->a_apl_refusal_planer,inst1);
					if(inst1==old_planer) bDeleteOld=false; // Есть в другой неисправностиж
				}
			}
		}
		if(bDeleteOld && index4Delete>=0)
		{
			inst=ext_wo[index4Delete];
			ext_wo.Remove(index4Delete);
			m_api->m_data.DeleteInstance(inst);
			bNeedSave=true;
		}
		if(bAdd)
		{
			inst=m_api->m_data.CreateInstance(wf_mgr->e_wo);
			m_api->m_data.PutAttr(inst,wf_mgr->a_wo_object,new_planer);
			m_api->m_data.PutAttr(inst,wf_mgr->a_wo_action,process);
			ext_wo.Add(inst);
			m_api->m_data.PutAttr(process, wf_mgr->a_proc_wo, ext_wo);
			bNeedSave=true;
		}
	}
	if(bNeedSave) m_api->SaveChanges();
	return true;
}

CString CaplFaultMgr::BuildSQL( CStringArray &saSQLparts , bool bUseOR)
{
	CString sUnionStr=_T(" AND ");
	if(bUseOR) sUnionStr =_T(" OR ");
	
	CString sResult = _T("SELECT Ext_1 FROM Ext_1 { apl_refusal(");

		// проходим по всем компонентам и "собираем по частям" наш запрос
	for(int i=0; i<saSQLparts.GetSize(); i+=3)
	{
		if(i!=0) sResult+=sUnionStr;
		sResult += (saSQLparts[i] + _T(" ") + saSQLparts[i+1] + _T(" ") + saSQLparts[i+2]);
	}

	// концовка
	return sResult += _T(")} END_SELECT");	
}

void CaplFaultMgr::ClearConditions()
{
	int i = 0;
	for(i=0; i<m_caConditionTmpl.GetSize(); i++) delete m_caConditionTmpl[i];
	for(i=0; i<m_caOperationsTmpl.GetSize(); i++) delete m_caOperationsTmpl[i];

	m_caOperationsTmpl.RemoveAll();
	m_caConditionTmpl.RemoveAll();
	m_saSQLparts.RemoveAll();
}

bool CaplFaultMgr::InitConditions()
{
	// все возможные условия
	CConditionOperation *equal = new CConditionOperation(APL_T("Равно"), _T("=")); m_caOperationsTmpl.Add(equal);
	CConditionOperation *not_equal = new CConditionOperation(APL_T("Не равно"), _T("!=")); m_caOperationsTmpl.Add(not_equal);
	CConditionOperation  *contain = new CConditionOperation(APL_T("Содержит"), _T("LIKE")); m_caOperationsTmpl.Add(contain);
	CConditionOperation *less = new CConditionOperation(APL_T("Меньше"), _T("<")); m_caOperationsTmpl.Add(less);
	CConditionOperation *more = new CConditionOperation(APL_T("Больше"), _T(">")); m_caOperationsTmpl.Add(more);

	CCondition *cond;

	// тип неисправности
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Тип неисправности"));
	cond->SetAttr(_T(".refusal_type"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_TYPE_CLASSIFIER_LVL), REFUSAL_TYPE_CLASSIFIER_LVL);
	cond->lpFuncChoose = &CaplFaultMgr::SelectClassifier;
	m_caConditionTmpl.Add(cond);

	// состояние неисправности
	cond = new CCondition();
	cond->SetName(APL_T("Состояние"));
	cond->SetAttr(_T(".state"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddDefaultValue(APL_T("Обнаружена"));
	cond->AddDefaultValue(APL_T("Подтверждена"));
	cond->AddDefaultValue(APL_T("Не подтверждена"));
	m_caConditionTmpl.Add(cond);

	// описание неисправности
	cond = new CCondition();
	cond->SetName(APL_T("Описание"));
	cond->SetAttr(_T(".description"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddOperation(contain);	
	m_caConditionTmpl.Add(cond);

	// документ неисправности
	cond = new CCondition();
	cond->SetName(APL_T("Документ"));
	cond->SetAttr(_T(".doc_type"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddDefaultValue(APL_T("Акт"));
	cond->AddDefaultValue(APL_T("Карточка Г"));
	cond->AddDefaultValue(APL_T("КУН"));
	cond->AddDefaultValue(APL_T("Сигнал"));
	cond->AddDefaultValue(APL_T("Карта возврата продукции"));
	m_caConditionTmpl.Add(cond);

	// номер документа неисправности
	cond = new CCondition();
	cond->SetName(APL_T("Номер документа"));
	cond->SetAttr(_T(".doc_num"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddOperation(contain);	
	m_caConditionTmpl.Add(cond);

	// дата оформления документа
	cond = new CCondition();
	cond->SetType(COND_DATE);
	cond->SetName(APL_T("Дата оформления документа"));
	cond->SetAttr(_T(".doc_date"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddOperation(less);	
	cond->AddOperation(more);	
	m_caConditionTmpl.Add(cond);

	// цех, где обнаружили
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Цех (внешняя организация)"));
	cond->SetAttr(_T(".org"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(0, APL_T("Цех, где обнаружена неисправность"));
	cond->lpFuncChoose = &CaplFaultMgr::SelectOrg;
	m_caConditionTmpl.Add(cond);

	// участок, где обнаружили
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Участок (подр. внешней организации)"));
	cond->SetAttr(_T(".sector"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(0, APL_T("Участок, где обнаружена неисправность"));
	cond->lpFuncChoose = &CaplFaultMgr::SelectOrg;
	m_caConditionTmpl.Add(cond);

	// этап
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Этап"));
	cond->SetAttr(_T(".stage"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_STAGE_CLASSIFIER_LVL), REFUSAL_STAGE_CLASSIFIER_LVL);
	cond->lpFuncChoose = &CaplFaultMgr::SelectClassifier;
	m_caConditionTmpl.Add(cond);

	// дата обнаружения
	cond = new CCondition();
	cond->SetType(COND_DATE);
	cond->SetName(APL_T("Дата обнаружения"));
	cond->SetAttr(_T(".date_detection"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddOperation(less);	
	cond->AddOperation(more);	
	m_caConditionTmpl.Add(cond);

	// дата устранения
	cond = new CCondition();
	cond->SetType(COND_DATE);
	cond->SetName(APL_T("Дата устранения"));
	cond->SetAttr(_T(".date_removal"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddOperation(less);	
	cond->AddOperation(more);	
	m_caConditionTmpl.Add(cond);

	// номер документа неисправности
	cond = new CCondition();
	cond->SetName(APL_T("Внешний вид"));
	cond->SetAttr(_T(".ext_view"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddOperation(contain);	
	m_caConditionTmpl.Add(cond);

	// основное изделие
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Основное изделие"));
	cond->SetAttr(_T(".planer->apl_product_instance.formation"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->lpFuncChoose = &CaplFaultMgr::SelectMainPdf;
	m_caConditionTmpl.Add(cond);

	// Экземпляр основного изделия
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Экземпляр основного изделия"));
	cond->SetAttr(_T(".planer"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->lpFuncChoose = &CaplFaultMgr::SelectItem;
	m_caConditionTmpl.Add(cond);



	// система
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Система"));
	cond->SetAttr(_T(".system"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->lpFuncChoose = &CaplFaultMgr::SelectSystem;
	m_caConditionTmpl.Add(cond);

	// Компонент (блок)
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Компонент (блок)"));
	cond->SetAttr(_T(".item"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->lpFuncChoose = &CaplFaultMgr::SelectItem;
	m_caConditionTmpl.Add(cond);

	// Отказавший элемент
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Отказавший элемент"));
	cond->SetAttr(_T(".part"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->lpFuncChoose = &CaplFaultMgr::SelectItem;
	m_caConditionTmpl.Add(cond);

	// обстоятельства обнаружения
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Обстоятельства обнаружения"));
	cond->SetAttr(_T(".conditions"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_CONDITIONS_CLASSIFIER_LVL), REFUSAL_CONDITIONS_CLASSIFIER_LVL);
	cond->lpFuncChoose = &CaplFaultMgr::SelectClassifier;
	m_caConditionTmpl.Add(cond);

	// Характер
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Характер"));
	cond->SetAttr(_T(".dof"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_DOF_CLASSIFIER_LVL), REFUSAL_DOF_CLASSIFIER_LVL);
	cond->lpFuncChoose = &CaplFaultMgr::SelectClassifier;
	m_caConditionTmpl.Add(cond);

	// Причина
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Причина"));
	cond->SetAttr(_T(".faultreason"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_REASON_CLASSIFIER_LVL), REFUSAL_REASON_CLASSIFIER_LVL);
	cond->lpFuncChoose = &CaplFaultMgr::SelectClassifier;
	m_caConditionTmpl.Add(cond);

	// Способ устранения
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Способ устранения"));
	cond->SetAttr(_T(".method"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_METHOD_CLASSIFIER_LVL), REFUSAL_METHOD_CLASSIFIER_LVL);
	cond->lpFuncChoose = &CaplFaultMgr::SelectClassifier;
	m_caConditionTmpl.Add(cond);

	// Последствия
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Последствия"));
	cond->SetAttr(_T(".consequences"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_CONSEQ_CLASSIFIER_LVL), REFUSAL_CONSEQ_CLASSIFIER_LVL);
	cond->lpFuncChoose = &CaplFaultMgr::SelectClassifier;
	m_caConditionTmpl.Add(cond);

	// Виновник
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Виновник"));
	cond->SetAttr(_T(".culprit"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(0, APL_T("Виновник"));
	cond->lpFuncChoose = &CaplFaultMgr::SelectOrg;
	m_caConditionTmpl.Add(cond);

	// Внешние проявления
	cond = new CCondition();
	cond->SetType(COND_INSTANCE);
	cond->SetName(APL_T("Внешние проявления"));
	cond->SetAttr(_T(".manifestation"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);
	cond->SetFuncParam(m_api->m_classifier_mgr.GetClassifierSystemBN(REFUSAL_MANIF_CLASSIFIER_LVL), REFUSAL_MANIF_CLASSIFIER_LVL);
	cond->lpFuncChoose = &CaplFaultMgr::SelectClassifier;
	m_caConditionTmpl.Add(cond);

	// описание внешнего проявления неисправности
	cond = new CCondition();
	cond->SetName(APL_T("Описание внешнего проявления"));
	cond->SetAttr(_T(".manif_str"));
	cond->AddOperation(equal);
	cond->AddOperation(not_equal);	
	cond->AddOperation(contain);	
	m_caConditionTmpl.Add(cond);

	return true;
}

CaplInstance* CaplFaultMgr::SelectClassifier(CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle)
{
	CaplInstance *ciLvl = 0;
	api->m_classifier_mgr.SelectItem(&ciLvl, ciRoot, APL_SELECT_CLASSIFIER_LEVEL, sTitle);

	return ciLvl;	
}

CaplInstance* CaplFaultMgr::SelectOrg( CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle )
{
	CaplInstance *ciOrg = 0;
	api->m_appr_mgr.SelectOrganization(&ciOrg, sTitle);

	return ciOrg;
}

CaplInstance* CaplFaultMgr::SelectMainPdf( CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle )
{
	CaplInstance *ciMain = 0;
	//mgr->SelectBaseItem(&ciMain, true);
	CString sSpavElement;
	api->m_options_mgr.GetOptionValueBN( APL_NO_T("Надежность\\Справочник для выбора изделий"),sSpavElement,_T(""));
	if(api->m_prd_mgr.FindPKIEx(&ciMain, 0, false, true,true,LPCTSTR(sSpavElement)))
	{		
		return ciMain;
	}
	return 0;
}

CaplInstance* CaplFaultMgr::SelectSystem( CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle )
{
	CaplInstance *ciSystem = 0;
	mgr->SelectPlanerSystem1(&ciSystem, aplSelectPlanerSystem, 0);

	return ciSystem;
}

CaplInstance* CaplFaultMgr::SelectItem( CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle )
{
	CaplInstance *ciItem = 0;
	mgr->FindPrdInst1(&ciItem, aplFindAllPrdInst);

	return ciItem;
}

bool CaplFaultMgr::FindRefusalBySQLFilter( CString &sSQL , bool &b_add_to_last_found )
{
	sSQL.Empty();
	CRefusalFilterDlg dlg(this);
	dlg.m_pSQLparts = &m_saSQLparts;

	if(dlg.DoModal() == IDOK)
	{
		b_add_to_last_found=dlg.m_add_to_last_found;
		sSQL = BuildSQL(m_saSQLparts, dlg.m_bUseOrCondition);	
		return true;
	}
	
	return false;
}

CString CaplFaultMgr::AskForPath(BOOL open, CString sExtension, CString sFilter)
{
	CString sPath;

	// узнаем куда сохранять
	if (sPath.IsEmpty())
	{
		CFileDialog dlg(open, sExtension, _T(""), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, sFilter);

		if (dlg.DoModal() != IDOK)
			return _T("");

		sPath = dlg.GetPathName();
	}

	return sPath;
}

bool CaplFaultMgr::SlaveUpdate(CStatusDlgThread *pStatus, CString text)
{
	pStatus->Slave_StepIt();
	pStatus->Slave_SetText(text);

	return true;
}

bool CaplFaultMgr::ExportWarningToManyRefusal(int size)
{
	if(size <= 2000) return true;
	if(MessageBox(0, APL_T("Вы собираетесь выгрузить более 1000 неисправностей.\nПроцесс может занять длительное время. Продолжить?"), APL_T("Внимание"), MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2) == IDYES) return true;

	return false;
}

CaplXMLNode* CaplFaultMgr::CreateNode(CaplXMLNode *root, CString name)
{
	CaplXMLNode *node = new CaplXMLNode;

	node->name = name;
	node->parent = root;
	root->subnodes.Add(node);

	return node;
}

int CaplFaultMgr::XMLImportGetCount( CaplXMLFile *file, CString path )
{
	long dID = aplStartWaitDlg(APL_T("Чтение файла..."));
	bool bResult = file->LoadFromFile(path);
	aplEndWaitDlg(dID);

	if(!bResult) return 0;
	if(!file->root.subnodes.GetSize()) return 0;

	int count = 0;
	CaplXMLNode *nodeRoot = file->root.subnodes[0];

	for(int i=0; i<nodeRoot->subnodes.GetSize(); i++)
	{
		// перебираем дочерние элементы
		CaplXMLNode *node = nodeRoot->subnodes[i];
		if(!node) continue;

		// ищем узел DATASET
		if(node->name != _T("DATASET")) continue;

		// берем узел DATA
		CaplXMLNode *nodeData = node->FindSingleNodeBN(_T("DATA"));
		if(!nodeData) continue;

		// берез узел неисправностей
		CaplXMLNode *nodeFaults = nodeData->FindSingleNodeBN(_T("FAULTS"));
		if(!nodeFaults) continue;

		// собираем кол-во
		count += nodeFaults->subnodes.GetSize();
	}

	return count;
}

bool CaplFaultMgr::ImportWarningToManyRefusal(CaplXMLFile *file, CString path)
{
	int size = XMLImportGetCount(file, path);
	if(size == 0) { MessageBox(0, APL_T("Неверный формат обменного файла!\nНе удалось определить количество импортируемых записей!"), APL_T("Ошибка"), MB_ICONSTOP); return false; } 
	CString msg;

	if(size > 2000)
	{
		msg.Format(APL_T("Обменный файл содержит %d записей о неисправностях.\nПроцесс импорта может занять длительное время. Продолжить?"), size);
		if(MessageBox(0, msg, APL_T("Внимание"), MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2) == IDYES) return true;
		else return false;
	}
		
	return true;
}

bool CaplFaultMgr::LoadRefusalsGUID(aplExtent &aeItems)
{
	if(!IsReadyForWork()) return false;
	if(!aeItems.Size) return false;

	int nCount = 0;
	CaplLoadData ld(&m_api->m_data, DEF_SOURCE);

	// загружаем только нужное
	for(int i=0; i<aeItems.Size; i++) 
	{
		if(!aeItems[i]->GetType()) continue;

		nCount++;
		ld.AddQuery(0, aeItems[i], true);

		if(nCount==m_nItemsPerOneLoad || i==(aeItems.Size-1))
		{
			ld.AddQuery(_T('d'), 0, m_ExplMgr->e_apl_refusal,  m_ExplMgr->a_apl_refusal_guid, true);
			ld.LoadEx(true, NULL);
			nCount = 0;
		}
	}	
	
	return true;
}

bool CaplFaultMgr::GetGUIDfromBase(map<CString, long> &baseGUIDs)
{
	CString guid;
	aplExtent aeRefusal;
	CString sSql = _T("SELECT Ext_1 FROM Ext_1 { apl_refusal.guid != '' } END_SELECT");

	long dID = aplStartWaitDlg(APL_T("Загрузка существующих неисправностей..."));
	if(m_api->m_data.NET_QueryEditParse(sSql, false) == false) return false;
	m_api->m_data.NET_QueryExecute(aeRefusal);

	LoadRefusalsGUID(aeRefusal);
	for(int i=0; i<aeRefusal.GetSize(); i++)
	{
		m_api->m_data.GetAttr(aeRefusal[i], m_ExplMgr->a_apl_refusal_guid, guid);		
		baseGUIDs.insert( Str_Long_Pair(guid, (long)aeRefusal[i]) );				
	}
	
	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::XMLImportParams(CaplInstance *ciRefusal, CaplXMLNode *node)
{
	CString strParam;

	node->GetParam(_T("GUID"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_guid, strParam);

	node->GetParam(_T("State"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_state, strParam);

	node->GetParam(_T("Description"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_description, strParam);

	node->GetParam(_T("DocumentType"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_type, strParam);

	node->GetParam(_T("DocumentNum"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_num, strParam);

	node->GetParam(_T("DocumentDate"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_date, strParam);

	node->GetParam(_T("DetectionDate"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_date_detection, strParam);

	node->GetParam(_T("RemovalDate"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_date_removal, strParam);

	node->GetParam(_T("ExternalView"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_ext_view, strParam);

	node->GetParam(_T("ResourcesString"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_resources_str, strParam);

	node->GetParam(_T("ManifistationString"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_manifestation_str, strParam);

	node->GetParam(_T("CommissionConclusion"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_result, strParam);

	node->GetParam(_T("NecassaryArrangments"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_necassary_arrangm, strParam);

	node->GetParam(_T("ResearchActNum"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_str, strParam);

	node->GetParam(_T("ResearchActDate"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_date, strParam);

	node->GetParam(_T("AcceptedArrangments"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_accepted_arrangements_str, strParam);

	node->GetParam(_T("DisposeData"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_dispose_data, strParam);

	node->GetParam(_T("ResultDicision"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_result_decision, strParam);

	node->GetParam(_T("ReclamationActNum"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_document_str, strParam);
	
	/*	
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_obj, ciResearchAct);
	if(ciResearchAct) { strParam = CreateGUID(); m_mapGuidDocument.Add(strParam, (void*)ciResearchAct); }
	else strParam = _T("");
	nodeRefusal->SetParam(_T("ResearchAct"), strParam);

	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_document_obj, ciReclamationAct);
	if(ciReclamationAct) { strParam = CreateGUID(); m_mapGuidDocument.Add(strParam, (void*)ciReclamationAct); }
	else strParam = _T("");
	nodeRefusal->SetParam(_T("ReclamationAct"), strParam);
	
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_parent, ciParent);
	if(ciParent) m_api->m_data.GetAttr(ciParent, m_ExplMgr->a_apl_refusal_state, strParam);
	nodeRefusal->SetParam(_T("ParentGUID"), strParam);
	*/

	return true;
}

bool CaplFaultMgr::ExportToXML( aplExtent &aeRefusal, CString path, bool loadRefusalAttr, bool loadRefusalCharacts, bool loadRefusalDocs )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!aeRefusal.Size) return false;
	if(!ExportWarningToManyRefusal(aeRefusal.Size)) return false;

	if(path.IsEmpty()) path = AskForPath(FALSE, _T("xml"), APL_T("Обменные файлы (*.xml)|*.xml||"));
	if(path.IsEmpty()) return false;

	// если нужно, загружаем всю информацию об отказах
	if(loadRefusalAttr) LoadRefusalInfo(aeRefusal);
	if(loadRefusalCharacts) LoadRefusalCharacts(aeRefusal);
	if(loadRefusalDocs) LoadRefusalDocuments(aeRefusal);

	// корень
	CaplXMLFile XMLfile;
	XMLfile.root.Clear();
	XMLfile.root.name = _T("XML");

	// узлы
	CaplXMLNode *nodeDataSet = CreateNode(&XMLfile.root, _T("DATASET"));
	CaplXMLNode *nodeData = CreateNode(nodeDataSet, _T("DATA"));
	CaplXMLNode *nodeFaults = CreateNode(nodeData, _T("FAULTS"));

	// массивы под каждый тип объекта
	aplExtent aeClassifierLvl;
	aplExtent aeOrganization;
	aplExtent aeLot;
	aplExtent aeCharact;
	aplExtent aeDocType;
	aplExtent aePrdInst;
	aplExtent aePdf;	
		
	// прогресс бар
	CString sProgressMsg;
	CaplInstance *ciRefusal = 0, *ciParent = 0;
	m_pStatus = CStatusDlgThread::aplCreateStatusThread(AfxGetMainWnd(), false, true);

	// главный размер = кол-во неисправностей + 8 категорий экспортируемых объектов
	m_pStatus->SetRange(0, aeRefusal.Size+1);
					
	sProgressMsg.Format(APL_T("Экспорт неисправностей:	0 / %d"), aeRefusal.Size);
	m_pStatus->SetText(sProgressMsg);	

	for(int i=0; i<aeRefusal.Size; i++)
	{
		// проверяем на вшивость
		ciRefusal = aeRefusal[i];
		if(!ciRefusal) continue;
		if(!ciRefusal->GetType()) continue;
		if(ciRefusal->GetAccessmode() > aplRO) continue;

		// неисправность
		CaplXMLNode *nodeRefusal = CreateNode(nodeFaults, _T("FAULT"));
		
		// текстовые атрибуты
		XMLExportRefusalParams(nodeRefusal, ciRefusal);		

		// ссылки на справочники
		XMLExportFaultClassifierLvlsRef(nodeRefusal, ciRefusal, aeClassifierLvl);		
				
		// организации
		XMLExportFaultOrganizationsRef(nodeRefusal, ciRefusal, aeOrganization);		

		// партии
		XMLExportFaultLotsRef(nodeRefusal, ciRefusal, aeLot);

		// прочие файлы
		XMLExportFiles(nodeRefusal, ciRefusal);

		// характеристики
		XMLExportCharactsValues(nodeRefusal, ciRefusal, aeCharact, aeOrganization);

		// документы
		XMLExportDocuments(nodeRefusal, ciRefusal, aeDocType);
		
		// экземпляры изделий
		XMLExportFaultPrdInstsRef(nodeRefusal, ciRefusal, aePrdInst);
				
		// показываем сколько уже экспортировано
		sProgressMsg.Format(APL_T("Экспорт неисправностей:	%d / %d"), i+1, aeRefusal.Size);
		m_pStatus->SetText(sProgressMsg);
		m_pStatus->StepIt();
	}
	m_pStatus->SetText(APL_T("Экспорт прочих объектов"));
		
	// создаем узлы использованных данных на которые ссылались атрибуты неисправностей
	XMLExportClassifierLvls(nodeData, aeClassifierLvl);
	
	XMLExportOrganizations(nodeData, aeOrganization); 
	
	XMLExportLots(nodeData, aeLot); 
	
	XMLExportCharacts(nodeData, aeCharact); 
	
	XMLExportDocTypes(nodeData, aeDocType); 
	
	XMLExportPrdInsts(nodeData, aePrdInst, aePdf); 
	
	XMLExportPrds(nodeData, aePdf); 
		
	m_api->SaveChanges();
	if(m_pStatus) m_pStatus->End();
	
	long dID = aplStartWaitDlg(APL_T("Сохранение обменного файла..."));
	bool bResult = XMLfile.SaveToFile(path);
	aplEndWaitDlg(dID);
	
	m_mapGuidDocument.Clear();	
	return bResult;
}

bool CaplFaultMgr::XMLExportFiles(CaplXMLNode *root, CaplInstance *ciRefusal)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	aplExtent aeFiles;
	CaplXMLNode *nodeFile = 0;
		
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_files, aeFiles);
	if(aeFiles.Size) nodeFile = CreateNode(root, _T("PICTURES"));

	for(int i=0; i<aeFiles.Size; i++) 
		XMLExportFile(aeFiles[i], nodeFile);

	return true;
}

bool CaplFaultMgr::XMLExportFile(CaplInstance *ciFile, CaplXMLNode *root)
{
	if(!ciFile) return false;
	if(!root) return false;

	long lSize = 0;
	BYTE *pbData = 0;
	CString sFileName, sEncodedFile;
	CaplXMLNode *nodePicture = CreateNode(root, _T("PICTURE"));

	// получаем файл и его имя
	m_api->m_data.GetAttr(ciFile, m_api->m_doc_mgr.a_apl_stored_document_file_name, sFileName);
	m_api->m_data.NET_GetBlobSize(ciFile, m_api->m_doc_mgr.a_apl_stored_document_source, lSize);
	if(lSize<=0) return false;
	pbData = new BYTE[lSize+1];
	m_api->m_data.NET_LoadBlob2Memory(ciFile,  m_api->m_doc_mgr.a_apl_stored_document_source, pbData, lSize);
	pbData[lSize] = _T('\0');

	// кодируем в base64
	sEncodedFile = EncodeToBase64(pbData, lSize);


	CaplXMLNode *nodeFile = CreateNode(nodePicture, _T("FILE"));
	nodeFile->SetParam(_T("file"), sFileName);
	nodeFile->SetParam(_T("content"), sEncodedFile);
	
	if(lSize) delete pbData;
	return true;
}

bool CaplFaultMgr::XMLExportDocuments(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeDocType)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	aplExtent aeDocuments, aeRelations;
	CaplXMLNode *nodeDocuments = 0;

	m_api->m_doc_mgr.FindAssociatedDocuments(ciRefusal, aeDocuments, aeRelations, 0, false);
	if(aeRelations.Size) nodeDocuments = CreateNode(root, _T("DOCUMENTS"));

	for(int i=0; i<aeRelations.Size; i++)
	{
		CaplInstance *ciDocument = 0;
		m_api->m_data.GetAttr(aeRelations[i], m_api->m_doc_mgr.a_apl_doc_ref_doc, ciDocument);
		if(ciDocument) XMLExportDocument(nodeDocuments, ciDocument, aeDocType);
	}

	return true;
}

bool CaplFaultMgr::XMLExportDocument(CaplXMLNode *root, CaplInstance *ciDocument, aplExtent &aeDocType)
{
	if(!ciDocument) return false;
	if(!root) return false;

	CaplXMLNode *nodeDocument = CreateNode(root, _T("DOCUMENT"));

	bool bValue;
	CaplInstance *ciKind = 0;
	CString sId, sName, sDescr, sCode, sAuthentic, sDTcode, sDependDesp, sDocLitera, sDTname;
	CString sStructKind, sIncludeDoc, sDocFormat, sDocSheets, sDocTotalSheets, sPart, sDTid;

	// текстовые атрибуты документа
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_id,					sId);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_name,					sName);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_descr,					sDescr);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_code,					sCode);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_add_dt_code,			sDTcode);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_code_depend_desp,		sDependDesp);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_struct_kind,			sStructKind);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_format,				sDocFormat);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_sheets,				sDocSheets);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_total_sheets_count,	sDocTotalSheets);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_litera,				sDocLitera);
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_part,					sPart);

	// булевые атрибуты документа
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_incl_in_doc,			bValue);
	if(bValue) sIncludeDoc = _T("1");
	else sIncludeDoc = _T("0");

	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_authentic,			bValue);
	if(bValue) sAuthentic = _T("1");
	else sAuthentic = _T("0");

	// тип документа
	XMLExportDocumentTypeRef(nodeDocument, ciDocument, aeDocType);

	// активная версия
	XMLExportActiveDocVersion(nodeDocument, ciDocument);
	
	nodeDocument->SetParam(_T("id"), sId);
	nodeDocument->SetParam(_T("name"), sName);
	nodeDocument->SetParam(_T("description"), sDescr);
	nodeDocument->SetParam(_T("code"), sCode);
	nodeDocument->SetParam(_T("authentic"), sAuthentic);
	nodeDocument->SetParam(_T("add_code"), sDTcode);
	nodeDocument->SetParam(_T("depend_desp"), sDependDesp);
	nodeDocument->SetParam(_T("struct_kind"), sStructKind);
	nodeDocument->SetParam(_T("include_in_doc"), sIncludeDoc);
	nodeDocument->SetParam(_T("format"), sDocFormat);
	nodeDocument->SetParam(_T("sheets"), sDocSheets);
	nodeDocument->SetParam(_T("total_sheets"), sDocTotalSheets);
	nodeDocument->SetParam(_T("litera"), sDocLitera);
	nodeDocument->SetParam(_T("part"), sPart);
	nodeDocument->SetParam(_T("reference_guid"), GetGuidFromMap(ciDocument));
	
	return true;
}

CString CaplFaultMgr::GetGuidFromMap(CaplInstance *ciDocument)
{
	int nIndex = m_mapGuidDocument.Find((long)ciDocument);
	if(nIndex == -1) return _T("");
	else return m_mapGuidDocument.GetAt(nIndex)->str;
}

bool CaplFaultMgr::XMLExportActiveDocVersion(CaplXMLNode *root, CaplInstance *ciDocument)
{
	if(!ciDocument) return false;
	if(!root) return false;

	CaplXMLNode *nodeDocVersion = CreateNode(root, _T("REVISION"));

	int nCRC;
	CaplInstance *ciRevision = 0, *ciFile = 0;
	CString sSheets, sTotalSheets,  sDescr, sStart, sContent;
	CString sId, sLabel, sFormat, sLitera, sEnd, sEditPath;

	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_apl_doc_active, ciRevision);
	
	// текстовые атрибуты
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_id, sId);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_label, sLabel);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_format, sFormat);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_litera, sLitera);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_descr, sDescr);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_crc, nCRC);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_start_s, sStart);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_end_s, sEnd);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_edit_path, sEditPath);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_sheets, sSheets);
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_total_sheets, sTotalSheets);

	// сам файл
	m_api->m_data.GetAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_access_form, ciFile);
	if(ciFile) XMLExportFile(ciFile, nodeDocVersion);
	
	nodeDocVersion->SetParam(_T("id"), sId);
	nodeDocVersion->SetParam(_T("label"), sLabel);
	nodeDocVersion->SetParam(_T("format"), sFormat);
	nodeDocVersion->SetParam(_T("litera"), sLitera);
	nodeDocVersion->SetParam(_T("description"), sDescr);
	nodeDocVersion->SetParam(_T("date_start"), sStart);
	nodeDocVersion->SetParam(_T("date_end"), sEnd);
	nodeDocVersion->SetParam(_T("edit_path"), sEditPath);
	nodeDocVersion->SetParam(_T("sheets"), sSheets);
	nodeDocVersion->SetParam(_T("total_sheets"), sTotalSheets);
	
	return true;
}

bool CaplFaultMgr::XMLExportDocumentTypeRef(CaplXMLNode *root, CaplInstance *ciDocument, aplExtent &aeDocType)
{
	if(!ciDocument) return false;
	if(!root) return false;

	CString sDTid, sDTname;
	CaplInstance *ciKind;
	m_api->m_data.GetAttr(ciDocument, m_api->m_doc_mgr.a_doc_kind, ciKind);

	if(ciKind)
	{
		m_api->m_data.GetAttr(ciKind, m_api->m_doc_mgr.a_dt_pdt, sDTid);
		aeDocType.Add(ciKind);
	}

	root->SetParam(_T("doc_type_name"), sDTid);
	return true;
}

CaplXMLNode* CaplFaultMgr::XMLExportDocTypes(CaplXMLNode *root, aplExtent &aeDocType)
{
	int i;
	CString sGuid, msg;
	CaplXMLNode *nodeDocTypes = 0;

	nodeDocTypes = CreateNode(root, _T("DOCUMENT_TYPES"));
	for(i=0; i<aeDocType.Size; i++)
		sGuid = XMLExportDocType(nodeDocTypes, aeDocType[i]);		
	
	return nodeDocTypes;
}

CString CaplFaultMgr::XMLExportDocType(CaplXMLNode *root, CaplInstance *ciDocType)
{
	if(!ciDocType) return false;
	if(!root) return false;

	CString sId, sGuid, sName, sSortNum;
	CaplXMLNode *node = CreateNode(root, _T("DOCUMENT_TYPE"));

	m_api->m_data.GetAttr(ciDocType, m_api->m_doc_mgr.a_dt_id, sId);
	m_api->m_data.GetAttr(ciDocType, m_api->m_doc_mgr.a_dt_pdt, sName);		
	m_api->m_data.GetAttr(ciDocType, m_api->m_doc_mgr.a_dt_sort_num, sSortNum);

	node->SetParam(_T("id"), sId);
	node->SetParam(_T("name"), sName);
	node->SetParam(_T("sort_num"), sSortNum);
	
	return sGuid;
}

bool CaplFaultMgr::XMLExportCharactsValues(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeCharact, aplExtent &aeOrganization)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	aplExtent aeCharVals;
	CaplXMLNode *nodeCharact = 0;
	
	m_api->m_charact_mgr.FindAssociatedCharacteristic(ciRefusal, aeCharVals, false, false, false, false);
	if(aeCharVals.Size) nodeCharact = CreateNode(root, _T("CHARACT_VALUES"));

	for(int i=0; i<aeCharVals.Size; i++) 
		XMLExportCharactValue(aeCharVals[i], nodeCharact, aeCharact, aeOrganization);

	return true;
}

bool CaplFaultMgr::XMLExportCharactValue(CaplInstance *ciCharVal, CaplXMLNode *root, aplExtent &aeCharact, aplExtent &aeOrganization)
{
	if(!ciCharVal) return false;
	if(!root) return false;

	CaplInstance *ciCharact, *ciAssignedType, *ciVal;
	CString sId, sAssignedTypeName, sType, sValue, sCharactId;
	CaplXMLNode *nodeCharVal = CreateNode(root, _T("CHARACT_VALUE"));
	double dValue;

	// характеристика
	m_api->m_data.GetAttr(ciCharVal, m_api->m_charact_mgr.a_apl_charact_val_charact, ciCharact);
	if(ciCharact)
	{
		CString buf;
		m_api->m_data.GetAttr(ciCharact, m_api->m_charact_mgr.a_apl_charact_id, sCharactId);
		aeCharact.Add(ciCharact);		
	}

	m_api->m_data.GetAttr(ciCharVal, m_api->m_charact_mgr.a_apl_charact_val_type, ciAssignedType);
	if(ciAssignedType) m_api->m_data.GetAttr(ciAssignedType, m_api->m_charact_mgr.a_apl_charact_type_name, sAssignedTypeName);

	// значение характеристики
	if(m_api->m_data.IsKindOf(ciCharVal, m_api->m_charact_mgr.e_descr_value))
	{
		sType = _T("descriptive");
		m_api->m_data.GetAttr(ciCharVal, m_api->m_charact_mgr.a_apl_charact_val_descr_val, sValue);
	}
	else if(m_api->m_data.IsKindOf(ciCharVal, m_api->m_charact_mgr.e_meas_value))
	{
		sType = _T("measure");
		m_api->m_data.GetAttr(ciCharVal, m_api->m_charact_mgr.a_apl_charact_val_meas_val, dValue);
		sValue.Format(_T("%g"), dValue);
	}
	else if(m_api->m_data.IsKindOf(ciCharVal, m_api->m_charact_mgr.e_monet_value))
	{
		sType = _T("monet");
		m_api->m_data.GetAttr(ciCharVal, m_api->m_charact_mgr.a_apl_charact_val_monet_val, dValue);
		sValue.Format(_T("%g"), dValue);
	}
	else if(m_api->m_data.IsKindOf(ciCharVal, m_api->m_charact_mgr.e_apl_reference_value))
	{
		sType = _T("organization");
		m_api->m_data.GetAttr(ciCharVal, m_api->m_charact_mgr.a_apl_reference_val, ciVal);
		if(ciVal) 
		{
			m_api->m_data.GetAttr(ciVal, m_api->m_appr_mgr.a_org_id, sValue);
			aeOrganization.Add(ciVal);
		}
	}
	else if(m_api->m_data.IsKindOf(ciCharVal, m_api->m_charact_mgr.e_time_val))
	{
		sType = _T("time");
		m_api->m_data.GetAttr(ciCharVal, m_api->m_charact_mgr.a_apl_charact_val_time_val_s, sValue);
	}

	nodeCharVal->SetParam(_T("assigned_type_name"), sAssignedTypeName);
	nodeCharVal->SetParam(_T("data_type"), sType);
	nodeCharVal->SetParam(_T("value"), sValue);
	nodeCharVal->SetParam(_T("charact_id"), sCharactId);
	
	return true;
}

bool CaplFaultMgr::XMLExportFaultPrdInstRef(CaplInstance *ciRefusal, CaplXMLNode *root, CaplAttr *attr, CString name, aplExtent &aePrdInst)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	CString sId, sSerialNo;
	CaplInstance *ciPrdInst;
	m_api->m_data.GetAttr(ciRefusal, attr, ciPrdInst);

	if(ciPrdInst)
	{
		// ПОКА ЧТО ИСКЛЮЧАЕМ ВОЗМОЖНОСТЬ ИМПОРТА ВЕРСИЙ ИЗДЕЛИЙ (АКТУАЛЬНО ДЛЯ ОТКАЗАВШЕГО ЭЛЕМЕНТА)
		if(m_api->m_data.IsKindOf(ciPrdInst, m_api->m_prd_mgr.e_pdf)) return false;

		CaplXMLNode *node = CreateNode(root, name);
		CaplXMLNode *nodeRef = CreateNode(node, _T("PRODUCT_INSTANCE_REF"));

		aePrdInst.Add(ciPrdInst);
		m_api->m_data.GetAttr(ciPrdInst, m_api->m_prd_inst_mgr.a_prd_inst_id, sId);
		m_api->m_data.GetAttr(ciPrdInst, m_api->m_prd_inst_mgr.a_prd_inst_sn, sSerialNo);

		nodeRef->SetParam(_T("id"), sId);
		nodeRef->SetParam(_T("serialno"), sSerialNo);		
	}

	return true;	
}

bool CaplFaultMgr::XMLExportFaultClassifierLvlRef(CaplInstance *ciRefusal, CaplXMLNode *root, CaplAttr *attr, CString name, aplExtent &aeClassifierLvl)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	CaplInstance *ciClassLvl;
	CString sId, sName, sDescr;

	m_api->m_data.GetAttr(ciRefusal, attr, ciClassLvl);
	if(ciClassLvl) 
	{
		m_api->m_data.GetAttr(ciClassLvl, m_api->m_classifier_mgr.a_apl_classifier_level_id, sId);
		aeClassifierLvl.Add(ciClassLvl);		
	}
		
	root->SetParam(name, sId);
	return true;
}

void CaplFaultMgr::SetReference(CaplMap &map, CaplInstance *ciItem, CString sGuid)
{
	int nIndex, nTempIndex;
	CaplXMLNode *node = 0;
	nIndex = map.QFindByIn((long)ciItem);

	// проходим по мапу вперед и назад, чтобы найти все совпадения
	if(nIndex > -1)
	{
		nTempIndex = nIndex;
		while(nTempIndex<map.Size && map[nTempIndex].in==(long)ciItem)
		{
			node = (CaplXMLNode*)map[nTempIndex].out;
			node->SetParam(_T("reference"), sGuid);
			nTempIndex++;
		}											

		nTempIndex=nIndex-1;
		while(nTempIndex>-1 && map[nTempIndex].in==(long)ciItem)
		{
			node = (CaplXMLNode*)map[nTempIndex].out;
			node->SetParam(_T("reference"), sGuid);
			nTempIndex--;
		}			
	}		
}

CString CaplFaultMgr::XMLExportPrdInst(CaplXMLNode *root, CaplInstance *ciPrdInst, aplExtent &aePdf)
{
	CaplInstance *ciPdf, *ciPrd;
	CString sId, sSN, sPrdId, sPdfId;
	CaplXMLNode *node = CreateNode(root, _T("PRODUCT_INSTANCE"));

	// артибуты экземпляра изделия
	m_api->m_data.GetAttr(ciPrdInst, m_api->m_prd_inst_mgr.a_prd_inst_sn, sSN);
	m_api->m_data.GetAttr(ciPrdInst, m_api->m_prd_inst_mgr.a_prd_inst_id, sId);

	// делаем ссылку на версию изделия
	m_api->m_data.GetAttr(ciPrdInst, m_api->m_prd_inst_mgr.a_prd_inst_pdf, ciPdf);
	if(ciPdf) 
	{
		CaplXMLNode *nodePdf = CreateNode(node, _T("PRODUCT_REF"));

		aePdf.Add(ciPdf);		
		m_api->m_data.GetAttr(ciPdf, m_api->m_prd_mgr.a_pdf_prd, ciPrd);
		m_api->m_data.GetAttr(ciPrd, m_api->m_prd_mgr.a_prd_id, sPrdId);
		m_api->m_data.GetAttr(ciPdf, m_api->m_prd_mgr.a_pdf_id, sPdfId);

		nodePdf->SetParam(_T("id"), sPrdId);
		nodePdf->SetParam(_T("ver_id"), sPdfId);
	}

	node->SetParam(_T("id"), sId);
	node->SetParam(_T("serialno"), sSN);
	
	return _T("");
}

CString CaplFaultMgr::XMLExportClassifierLvl(CaplXMLNode *root, CaplInstance *ciLvl)
{
	CString sId, sName, sDescr, sGuid;
	CaplXMLNode *node = CreateNode(root, _T("CLASSIFIER_LEVEL"));
	
	m_api->m_data.GetAttr(ciLvl, m_api->m_classifier_mgr.a_apl_classifier_level_id, sId);
	m_api->m_data.GetAttr(ciLvl, m_api->m_classifier_mgr.a_apl_classifier_level_name, sName);
	m_api->m_data.GetAttr(ciLvl, m_api->m_classifier_mgr.a_apl_classifier_level_descr, sDescr);

	node->SetParam(_T("id"), sId);
	node->SetParam(_T("name"), sName);
	node->SetParam(_T("description"), sDescr);	

	return sGuid;
}

CString CaplFaultMgr::XMLExportCharact(CaplXMLNode *root, CaplInstance *ciCharact)
{
	CString sId, sGuid, sName;
	CaplXMLNode *node = CreateNode(root, _T("CHARACT"));

	m_api->m_data.GetAttr(ciCharact, m_api->m_charact_mgr.a_apl_charact_id, sId);		
	m_api->m_data.GetAttr(ciCharact, m_api->m_charact_mgr.a_apl_charact_name, sName);

	node->SetParam(_T("id"), sId);
	node->SetParam(_T("name"), sName);
	
	return sGuid;
}

CaplXMLNode* CaplFaultMgr::XMLExportCharacts(CaplXMLNode *root, aplExtent &aeCharact)
{
	int i;
	CString sGuid, msg;
	CaplXMLNode *nodeCharacts = 0;

	nodeCharacts = CreateNode(root, _T("CHARACTS"));
	for(i=0; i<aeCharact.Size; i++)
		sGuid = XMLExportCharact(nodeCharacts, aeCharact[i]);		
	
	return nodeCharacts;
}

CString CaplFaultMgr::XMLExportLot(CaplXMLNode *root, CaplInstance *ciLot)
{
	CString sId, sGuid;
	CaplXMLNode *node = CreateNode(root, _T("LOT"));

	sGuid = CreateGUID();
	m_api->m_data.GetAttr(ciLot, m_api->m_prd_inst_mgr.a_lot_id, sId);

	node->SetParam(_T("id"), sId);
	node->SetParam(_T("reference_guid"), sGuid);

	return sGuid;
}

CaplXMLNode* CaplFaultMgr::XMLExportLots(CaplXMLNode *root, aplExtent &aeLot)
{
	int i;
	CString sGuid, msg;
	CaplXMLNode *nodeLots = 0;

	nodeLots = CreateNode(root, _T("LOTS"));
	for(i=0; i<aeLot.Size; i++)
		sGuid = XMLExportLot(nodeLots, aeLot[i]);		
	
	return nodeLots;
}

CString CaplFaultMgr::XMLExportOrganization(CaplXMLNode *root, CaplInstance *ciOrg)
{
	CString sId, sName, sGuid;
	CaplXMLNode *node = CreateNode(root, _T("ORGANIZATION"));

	m_api->m_data.GetAttr(ciOrg, m_api->m_appr_mgr.a_org_id, sId);
	m_api->m_data.GetAttr(ciOrg, m_api->m_appr_mgr.a_org_name, sName);
	
	node->SetParam(_T("id"), sId);
	node->SetParam(_T("name"), sName);
	
	return sGuid;
}

CaplXMLNode* CaplFaultMgr::XMLExportOrganizations(CaplXMLNode *root, aplExtent &aeOrganization)
{
	int i;
	CString sGuid, msg;
	CaplXMLNode *nodeOrganizations = 0;

	nodeOrganizations = CreateNode(root, _T("ORGANIZATIONS"));
	for(i=0; i<aeOrganization.Size; i++)
		sGuid = XMLExportOrganization(nodeOrganizations, aeOrganization[i]);				
	
	return nodeOrganizations;
}

CaplXMLNode* CaplFaultMgr::XMLExportPrds(CaplXMLNode *root, aplExtent &aePdf)
{
	int i;
	CString sGuid, msg;
	CaplXMLNode *nodePrds = 0;

	nodePrds = CreateNode(root, _T("PRODUCTS"));
	for(i=0; i<aePdf.Size; i++)
		sGuid = XMLExportPrd(nodePrds, aePdf[i]);		
	
	return nodePrds;
}

CString CaplFaultMgr::XMLExportPrd(CaplXMLNode *root, CaplInstance *ciPdf)
{
	CString buf;
	CaplInstance *ciPrd = 0;
	CString sId, sName, sGuid, sVer;
	CaplXMLNode *nodePrd = CreateNode(root, _T("PRODUCT"));

	m_api->m_data.GetAttr(ciPdf, m_api->m_prd_mgr.a_pdf_prd, ciPrd);
	m_api->m_data.GetAttr(ciPdf, m_api->m_prd_mgr.a_pdf_id, sVer);
	
	// артибуты экземпляра изделия
	m_api->m_data.GetAttr(ciPrd, m_api->m_prd_mgr.a_prd_id, sId);
	m_api->m_data.GetAttr(ciPrd, m_api->m_prd_mgr.a_prd_name, sName);
	
	nodePrd->SetParam(_T("id"), sId);
	nodePrd->SetParam(_T("name"), sName);
	nodePrd->SetParam(_T("product_ver"), sVer);
	
	return sGuid;
}

bool CaplFaultMgr::LoadIPrdInstPdfAndPrdInfo(aplExtent &aeItems)
{
	if(!IsReadyForWork()) return false;
	if(!aeItems.Size) return false;

	long dID = aplStartWaitDlg(APL_T("Загрузка атрибутов для экземпляров изделий..."));

	int nCount = 0;
	CaplLoadData ld(&m_api->m_data, DEF_SOURCE);

	// загружаем только нужное
	for(int i=0; i<aeItems.Size; i++) 
	{
		if(!aeItems[i]) continue;
		if(!aeItems[i]->GetType()) continue;

		nCount++;
		ld.AddQuery(0, aeItems[i], true);

		if(nCount==m_nItemsPerOneLoad || i==(aeItems.Size-1))
		{
			int m1 =	ld.AddQuery(_T('d'), 0, m_api->m_prd_inst_mgr.e_prd_inst, m_api->m_prd_inst_mgr.a_prd_inst_pdf, true, true);
			int m2 =	ld.AddQuery(_T('d'), m1, m_api->m_prd_mgr.e_pdf, m_api->m_prd_mgr.a_pdf_prd, true);
						ld.AddQuery(_T('d'), m2, m_api->m_prd_mgr.e_prd, m_api->m_prd_mgr.a_prd_id, true);			

			ld.LoadEx(true, NULL);
			nCount = 0;
		}
	}	

	aplEndWaitDlg(dID);
	return true;
}

CaplXMLNode* CaplFaultMgr::XMLExportPrdInsts(CaplXMLNode *root, aplExtent &aePrdInst, aplExtent &aePdf)
{
	int i;
	CString sGuid, msg;
	CaplXMLNode *nodePrdInsts = 0;

	nodePrdInsts = CreateNode(root, _T("PRODUCT_INSTANCES"));
	LoadIPrdInstPdfAndPrdInfo(aePrdInst);

	for(i=0; i<aePrdInst.Size; i++)
		sGuid = XMLExportPrdInst(nodePrdInsts, aePrdInst[i], aePdf);		
	
	return nodePrdInsts;
}

CaplXMLNode* CaplFaultMgr::XMLExportClassifierLvls(CaplXMLNode *root, aplExtent &aeClassifierLvl)
{
	int i;
	CString sGuid, msg;
	CaplXMLNode *nodeClassLvls = 0;

	nodeClassLvls = CreateNode(root, _T("CLASSIFIER_LEVELS"));
	for(i=0; i<aeClassifierLvl.Size; i++)
		sGuid = XMLExportClassifierLvl(nodeClassLvls, aeClassifierLvl[i]);		
			
	return nodeClassLvls;
}

bool CaplFaultMgr::XMLExportFaultClassifierLvlsRef(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeClassifierLvl)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_type, _T("failure_mode"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_stage, _T("failure_stage"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_conditions, _T("detection_context"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_manifestation, _T("symptom"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_dof, _T("nature"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_faultreason, _T("reason"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_method, _T("recovery_method"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_consequences, _T("effect"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_test_deduction, _T("test_deduction"), aeClassifierLvl);
	XMLExportFaultClassifierLvlRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_culprit_deduction, _T("culprit_deduction"), aeClassifierLvl);

	return true;
}

bool CaplFaultMgr::XMLExportFaultOrganizationRef(CaplInstance *ciRefusal, CaplXMLNode *root, CaplAttr *attr, CString name, aplExtent &aeOrganization)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	CString sId;
	CaplInstance *ciOrg;
	m_api->m_data.GetAttr(ciRefusal, attr, ciOrg);

	if(ciOrg)
	{
		m_api->m_data.GetAttr(ciOrg, m_api->m_appr_mgr.a_org_id, sId);
		aeOrganization.Add(ciOrg);
	}

	root->SetParam(name, sId);
	return true;
}

bool CaplFaultMgr::XMLExportFaultOrganizationsRef(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeOrganization)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	XMLExportFaultOrganizationRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_culprit, _T("failure_cause_originator"), aeOrganization);
	XMLExportFaultOrganizationRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_org, _T("workshop"), aeOrganization);
	XMLExportFaultOrganizationRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_sector, _T("sector"), aeOrganization);
	XMLExportFaultOrganizationRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_research_lab, _T("research_lab"), aeOrganization);
	XMLExportFaultOrganizationRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_research_sector, _T("research_workshop"), aeOrganization);

	return true;
}

bool CaplFaultMgr::XMLExportFaultPrdInstsRef(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aePrdInst)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	CaplXMLNode *nodePrdInsts = CreateNode(root, _T("LOCATION"));
	
	XMLExportFaultPrdInstRef(ciRefusal, nodePrdInsts, m_ExplMgr->a_apl_refusal_planer, _T("MAIN_PRODUCT"), aePrdInst);
	XMLExportFaultPrdInstRef(ciRefusal, nodePrdInsts, m_ExplMgr->a_apl_refusal_system, _T("SYSTEM"), aePrdInst);
	XMLExportFaultPrdInstRef(ciRefusal, nodePrdInsts, m_ExplMgr->a_apl_refusal_item, _T("BLOCK"), aePrdInst);
	XMLExportFaultPrdInstRef(ciRefusal, nodePrdInsts, m_ExplMgr->a_apl_refusal_part, _T("ELEMENT"), aePrdInst);

	return true;
}

bool CaplFaultMgr::XMLExportFaultLotsRef(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeLot)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	XMLExportFaultLotRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_item_lot, _T("block_lot"), aeLot);
	XMLExportFaultLotRef(ciRefusal, root, m_ExplMgr->a_apl_refusal_part_lot, _T("element_lot"), aeLot);

	return true;
}

bool CaplFaultMgr::XMLExportFaultLotRef(CaplInstance *ciRefusal, CaplXMLNode *root, CaplAttr *attr, CString name, aplExtent &aeLot)
{
	if(!ciRefusal) return false;
	if(!root) return false;

	CString sId;
	CaplInstance *ciLot;
	m_api->m_data.GetAttr(ciRefusal, attr, ciLot);

	if(ciLot)
	{
		m_api->m_data.GetAttr(ciLot, m_api->m_prd_inst_mgr.a_lot_id, sId);
		aeLot.Add(ciLot);
	}

	root->SetParam(name, sId);
	return true;
}

bool CaplFaultMgr::XMLExportRefusalParams(CaplXMLNode *nodeRefusal, CaplInstance *ciRefusal)
{
	CString strParam, sGuid;
	CaplInstance *ciParent, *ciResearchAct, *ciReclamationAct;

	// родительская неисправность +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_parent, ciParent);
	if(ciParent) 
	{
		m_api->m_data.GetAttr(ciParent, m_ExplMgr->a_apl_refusal_guid, strParam);
		if(strParam.IsEmpty())
		{
			strParam = CreateGUID();
			m_api->m_data.PutAttr(ciParent, m_ExplMgr->a_apl_refusal_guid, strParam);
		}
		nodeRefusal->SetParam(_T("parent_id"), strParam);
	}

	// собственный guid +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_guid, strParam);
	if(strParam.IsEmpty())
	{
		strParam = CreateGUID();
		m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_guid, strParam);
	}
	nodeRefusal->SetParam(_T("id"), strParam);

	// состояние +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_state, strParam);
	nodeRefusal->SetParam(_T("state"), strParam);

	// описание +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_description, strParam);
	nodeRefusal->SetParam(_T("notes"), strParam);

	// тип документа +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_type, strParam);
	nodeRefusal->SetParam(_T("document_type"), strParam);

	// номер документа +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_num, strParam);
	nodeRefusal->SetParam(_T("document_num"), strParam);

	// дата оформления документа +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_date, strParam);
	nodeRefusal->SetParam(_T("document_date"), strParam);

	// дата обнаружения +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_date_detection, strParam);
	nodeRefusal->SetParam(_T("detection_date_time"), strParam);

	// дата устранения +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_date_removal, strParam);
	nodeRefusal->SetParam(_T("recovery_date_time"), strParam);

	// внешний вид (состояние) +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_ext_view, strParam);
	nodeRefusal->SetParam(_T("external_view"), strParam);

	// внешнее проявление (строкой) +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_manifestation_str, strParam);
	nodeRefusal->SetParam(_T("manifistation_string"), strParam);

	// резултаты исследования +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_result, strParam);
	nodeRefusal->SetParam(_T("commission_conclusion"), strParam);

	// необходимые мероприятия +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_necassary_arrangm, strParam);
	nodeRefusal->SetParam(_T("necassary_arrangments"), strParam);

	// номер акта исследования +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_str, strParam);
	nodeRefusal->SetParam(_T("research_act_num"), strParam);

	// дата оформления акта исследования +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_date, strParam);
	nodeRefusal->SetParam(_T("research_act_date"), strParam);

	// принятые меры +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_accepted_arrangements_str, strParam);
	nodeRefusal->SetParam(_T("actions"), strParam);

	// сведения об устраенении +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_dispose_data, strParam);
	nodeRefusal->SetParam(_T("dispose_data"), strParam);

	// итоговое решение (решение комиссии) +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_result_decision, strParam);
	nodeRefusal->SetParam(_T("result_dicision"), strParam);

	// номер рекламационного акта +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_document_str, strParam);
	nodeRefusal->SetParam(_T("reclamation_report"), strParam);

	// обозначение документа "Акт исследования" +
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_obj, ciResearchAct);
	if(ciResearchAct) m_api->m_data.GetAttr(ciResearchAct, m_api->m_doc_mgr.a_doc_id, strParam);
	else strParam = _T("");
	nodeRefusal->SetParam(_T("research_act"), strParam);

	// обозначение документа "Рекламационный акт" + 
	m_api->m_data.GetAttr(ciRefusal, m_ExplMgr->a_apl_refusal_document_obj, ciReclamationAct);
	if(ciResearchAct) m_api->m_data.GetAttr(ciResearchAct, m_api->m_doc_mgr.a_doc_id, strParam);
	else strParam = _T("");
	nodeRefusal->SetParam(_T("reclamation_act"), strParam);
	
	return true;
}

CString CaplFaultMgr::CreateGUID()
{
	CString guid=_T("");

	::CoInitialize(NULL);
	GUID pGuid = GUID_NULL;
	::CoCreateGuid(&pGuid);
	if(pGuid==GUID_NULL) return _T("");
	
	guid.Format(_T("{%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
		pGuid.Data1, pGuid.Data2, pGuid.Data3,
		pGuid.Data4[0], pGuid.Data4[1], pGuid.Data4[2], pGuid.Data4[3],
		pGuid.Data4[4], pGuid.Data4[5], pGuid.Data4[6], pGuid.Data4[7]);

	::CoUninitialize();
	return guid;
}

CString CaplFaultMgr::EncodeToBase64( unsigned char const* BYTEs_to_encode, unsigned int in_len )
{
	CString ret;
	int i = 0;
	int j = 0;
	unsigned char char_array_3[3];
	unsigned char char_array_4[4];

	while (in_len--) 
	{
		char_array_3[i++] = *(BYTEs_to_encode++);
		if (i == 3) 
		{
			char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
			char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
			char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
			char_array_4[3] = char_array_3[2] & 0x3f;

			for(i = 0; (i <4) ; i++)
				ret += base64_chars[char_array_4[i]];
			i = 0;
		}
	}

	if (i)
	{
		for(j = i; j < 3; j++)
			char_array_3[j] = _T('\0');

		char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
		char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
		char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
		char_array_4[3] = char_array_3[2] & 0x3f;

		for (j = 0; (j < i + 1); j++)
			ret += base64_chars[char_array_4[j]];

		while((i++ < 3))
			ret += _T('=');

	}

	return ret;
}

CString CaplFaultMgr::DecodeFromBase64( CString encoded_string )
{
#ifdef UNICODE
	TRACE(_T("Ошибка! Функция не поддерживается версией для Unicode (CaplFaultMgr::DecodeFromBase64)!"));
	CString ret;
	return ret;
#else
	int in_len = encoded_string.GetLength();
	int i = 0;
	int j = 0;
	int in_ = 0;
	unsigned char char_array_4[4], char_array_3[3];
	CString ret;

	while (in_len-- && ( encoded_string[in_] != _T('=')) && is_base64(encoded_string[in_])) 
	{
		char_array_4[i++] = encoded_string[in_]; in_++;
		if (i ==4) 
		{
			for (i = 0; i <4; i++)
				char_array_4[i] = base64_chars.find(char_array_4[i]);

			char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
			char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
			char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

			for (i = 0; (i < 3); i++)
				ret += char_array_3[i];
			i = 0;
		}
	}

	if (i) 
	{
		for (j = i; j <4; j++)
			char_array_4[j] = 0;

		for (j = 0; j <4; j++)
			char_array_4[j] = base64_chars.find(char_array_4[j]);

		char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
		char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
		char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

		for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
	}

	return ret;
#endif
}

CaplXMLNode* CaplFaultMgr::GetChildNodeBN(CaplXMLNode *node, CString name)
{
	if(!node) return 0;

	for(int i=0; i<node->subnodes.GetSize(); i++)
		if(node->subnodes[i]->name == name)
			return node->subnodes[i];

	return 0;
}

bool CaplFaultMgr::ImportFromXML( CString path /*= _T("")*/ )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(path.IsEmpty()) path = AskForPath(TRUE, _T("xml"), APL_T("Обменные файлы (*.xml)|*.xml|Все файлы (*.*)|*.*||"));
	if(path.IsEmpty()) return false;

	CaplXMLFile file;
	if(!ImportWarningToManyRefusal(&file, path)) return false;

	// ищем неиспарвности с заполенными guid в базе (чтобы не было повторов при импорте)
	map<CString, long> baseGUIDs;
	map<CString, long>::iterator Iter;
	if(!GetGUIDfromBase(baseGUIDs)) return false;

	// наборы объектов
	map<CString, long> mapClassifierLvls;
	map<CString, long> mapOrganizations;
	map<CString, long> mapLots;
	map<CString, long> mapCharacts;
	map<CString, long> mapDocumentTypes;
	map<CString, long> mapDefinitions;
	map<CString, long> mapCharactTypes;
	map<CString, long> mapDocument;
	map<CString, long> mapInstances;

	map<Str_Str_Pair, long> mapProducts;

	// остальные переменные
	CString sGuid, sParentGuid;
	CaplInstance *ciRefusal = 0;

	// импортируем
	for(int i=0; i<file.root.subnodes[0]->subnodes.GetSize(); i++)
	{
		// перебираем дочерние элементы
		CaplXMLNode *node = file.root.subnodes[0]->subnodes[i];
		if(!node) continue;

		// ищем узел DATASET
		if(node->name != _T("DATASET")) continue;

		// берем узел DATA
		CaplXMLNode *nodeData = node->FindSingleNodeBN(_T("DATA"));
		if(!nodeData) continue;

		// справочники
		XMLGetClassifierLevels(GetChildNodeBN(nodeData, _T("CLASSIFIER_LEVELS")), mapClassifierLvls);

		// организации
		XMLGetOrganiztions(GetChildNodeBN(nodeData, _T("ORGANIZATIONS")), mapOrganizations);

		// партии
		XMLGetLots(GetChildNodeBN(nodeData, _T("LOTS")), mapLots);

		// характеристики и их типы
		XMLGetCharactsAndTypes(GetChildNodeBN(nodeData, _T("CHARACTS")), mapCharacts, mapCharactTypes);

		// типы документов
		XMLGetDocumentTypes(GetChildNodeBN(nodeData, _T("DOCUMENT_TYPES")), mapDocumentTypes);

		//изделия и их версии
		XMLGetProducts(GetChildNodeBN(nodeData, _T("PRODUCTS")), mapProducts);

		// экземпляры изделий
		XMLGetProductInstances(GetChildNodeBN(nodeData, _T("PRODUCT_INSTANCES")), mapInstances, mapProducts);

		// неисправности
		CaplXMLNode *nodeFaults = GetChildNodeBN(nodeData, _T("FAULTS"));
		if(!nodeFaults) continue;

		aplExtent aeNewFaults;
		map<CString, long> mapChildFaults;

		for(int j=0; j<nodeFaults->subnodes.GetSize(); j++)
		{	
			CaplXMLNode *nodeFault = nodeFaults->subnodes[j] ;

			// получаем guid
			sGuid = nodeFault->GetParam(_T("id"));
			if(sGuid.IsEmpty()) continue;
			
			// ищем среди существующих
			Iter = baseGUIDs.find(sGuid);
			if(Iter != baseGUIDs.end()) continue;

			// создаем 
			ciRefusal = m_api->m_data.CreateInstance(m_ExplMgr->e_apl_refusal);
			if(!ciRefusal) continue;
			else aeNewFaults.Add(ciRefusal);
			
			// смотрим является ли дочерней
			sParentGuid = nodeFault->GetParam(_T("parent_id"));
			if(!sParentGuid.IsEmpty()) mapChildFaults.insert(Str_Long_Pair(sParentGuid, (long)ciRefusal));

			// импортируем справочники
			XMLImprotClassifierLevels(nodeFault, ciRefusal, mapClassifierLvls);

			// импортируем организации
			XMLImprotOrganizations(nodeFault, ciRefusal, mapOrganizations);

			// импортируем партии
			XMLImprotLots(nodeFault, ciRefusal, mapLots);

			// импортируем изображения
			XMLImportPictures(nodeFault, ciRefusal);

			// импортируем характеристики
			XMLImportCharValues(nodeFault, ciRefusal, mapCharacts, mapCharactTypes, mapOrganizations);

			// импортируем документы
			XMLImprotDocuments(nodeFault, ciRefusal, mapDocumentTypes, mapDocument);

			// ассоциируем с экземплярами изделий в базе
			XMLImportProductInstances(nodeFault, ciRefusal, mapInstances);

			//  добавляем строковые атрибуты
			XMLImprotStringAttrs(nodeFault, ciRefusal, mapDocument);
		}

		// добавляем новые к существующим
		AppendGuidMap(baseGUIDs, aeNewFaults);

		// проставляем родительско-дочерние связи
		MakeTreeStruct(baseGUIDs, mapChildFaults);
	}	

	m_api->SaveChanges();
	return true;
}

bool CaplFaultMgr::MakeTreeStruct(map<CString, long> &baseGuids, map<CString, long> &childGuids)
{
	CString strParam;
	map<CString, long>::iterator IterBase, IterChild;

	for(IterChild = childGuids.begin(); IterChild != childGuids.end(); IterChild++)
	{
		strParam = IterChild->first;
		IterBase = baseGuids.find(strParam);

		if(IterBase != baseGuids.end())
			m_api->m_data.PutAttr((CaplInstance*)IterChild->second, m_ExplMgr->a_apl_refusal_parent, (CaplInstance*)IterBase->second);
	}

	return true;
}

bool CaplFaultMgr::AppendGuidMap(map<CString, long> &baseGuids, aplExtent &aeNewFaults)
{
	CString strParam;

	for(int i=0; i<aeNewFaults.Size; i++)
	{
		m_api->m_data.GetAttr(aeNewFaults[i], m_ExplMgr->a_apl_refusal_guid, strParam);
		if(!strParam.IsEmpty()) baseGuids.insert(Str_Long_Pair(strParam, (long)aeNewFaults[i]));
	}

	return true;
}

bool CaplFaultMgr::XMLGetClassifierLevels( CaplXMLNode *node, map<CString, long> &mapLvl )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!node) return false;

	// переменные
	long dID;
	int i, m1;
	CString sId;
	aplExtent aeItems;
	CaplLoadData ld(&m_api->m_data);
	map<CString, long>::iterator Iter;

	dID = aplStartWaitDlg(APL_T("Построение ссылок на справочники..."));

	// берем обозначения всех справочников из xml
	for(i=0; i<node->subnodes.GetSize(); i++)
	{
		CString sId = node->subnodes[i]->GetParam(_T("id"));
		if(!sId.IsEmpty()) mapLvl.insert(Str_Long_Pair(sId, 0));		
	}

	// берем все справочники из базы
	m1 =	ld.AddQuery(_T('e'), 0, m_api->m_classifier_mgr.e_apl_classifier_level, 0, true);
			ld.AddQuery(_T('d'), m1, m_api->m_classifier_mgr.e_apl_classifier_level, m_api->m_classifier_mgr.a_apl_classifier_level_id, true);
	ld.LoadEx(true);
	m_api->m_data.GetEntityExtent(m_api->m_classifier_mgr.e_apl_classifier_level, aeItems);

	// находим соответствия
	for(i=0; i<aeItems.Size; i++)
	{
		m_api->m_data.GetAttr(aeItems[i], m_api->m_classifier_mgr.a_apl_classifier_level_id, sId);
		if(sId.IsEmpty()) continue;

		Iter = mapLvl.find(sId);
		if(Iter != mapLvl.end()) 
			Iter->second = (long)aeItems[i];		
	}

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::XMLGetOrganiztions( CaplXMLNode *node, map<CString, long> &mapOrg )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!node) return false;

	// переменные
	long dID;
	int i, m1;
	CString sId;
	aplExtent aeItems;
	CaplLoadData ld(&m_api->m_data);
	map<CString, long>::iterator Iter;

	dID = aplStartWaitDlg(APL_T("Построение ссылок на организации..."));

	// берем обозначения всех организаций из xml
	for(i=0; i<node->subnodes.GetSize(); i++)
	{
		CString sId = node->subnodes[i]->GetParam(_T("id"));
		if(!sId.IsEmpty()) mapOrg.insert(Str_Long_Pair(sId, 0));				
	}

	// берем все организации из базы
	m1 =	ld.AddQuery(_T('e'), 0, m_api->m_appr_mgr.e_org, 0, true);
	ld.AddQuery(_T('d'), m1, m_api->m_appr_mgr.e_org, m_api->m_appr_mgr.a_org_id, true);
	ld.LoadEx(true);
	m_api->m_data.GetEntityExtent(m_api->m_appr_mgr.e_org, aeItems);

	// находим соответствия
	for(i=0; i<aeItems.Size; i++)
	{
		m_api->m_data.GetAttr(aeItems[i], m_api->m_appr_mgr.a_org_id, sId);
		if(sId.IsEmpty()) continue;

		Iter = mapOrg.find(sId);
		if(Iter != mapOrg.end()) 
			Iter->second = (long)aeItems[i];		
	}

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::XMLGetLots( CaplXMLNode *node, map<CString, long> &mapLot )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!node) return false;

	// переменные
	long dID;
	int i, m1;
	CString sId;
	aplExtent aeItems;
	CaplLoadData ld(&m_api->m_data);
	map<CString, long>::iterator Iter;

	dID = aplStartWaitDlg(APL_T("Построение ссылок на партии..."));

	// берем обозначения всех партий из xml
	for(i=0; i<node->subnodes.GetSize(); i++)
	{
		CString sId = node->subnodes[i]->GetParam(_T("id"));
		if(!sId.IsEmpty()) mapLot.insert(Str_Long_Pair(sId, 0));		
	}

	// берем все партии из базы
	m1 =	ld.AddQuery(_T('e'), 0, m_api->m_prd_inst_mgr.e_lot, 0, true);
	ld.AddQuery(_T('d'), m1, m_api->m_prd_inst_mgr.e_lot, m_api->m_prd_inst_mgr.a_lot_id, true);
	ld.LoadEx(true);
	m_api->m_data.GetEntityExtent(m_api->m_prd_inst_mgr.e_lot, aeItems);

	// находим соответствия
	for(i=0; i<aeItems.Size; i++)
	{
		m_api->m_data.GetAttr(aeItems[i], m_api->m_prd_inst_mgr.a_lot_id, sId);
		if(sId.IsEmpty()) continue;

		Iter = mapLot.find(sId);
		if(Iter != mapLot.end()) 
			Iter->second = (long)aeItems[i];		
	}

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::XMLGetDocumentTypes( CaplXMLNode *node, map<CString, long> &mapDT )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!node) return false;

	// переменные
	long dID;
	int i, m1;
	CString sId;
	aplExtent aeItems;
	CaplLoadData ld(&m_api->m_data);
	map<CString, long>::iterator Iter;

	dID = aplStartWaitDlg(APL_T("Построение ссылок на типы документов..."));

	// берем обозначения всех типов документов из xml 
	for(i=0; i<node->subnodes.GetSize(); i++)
	{
		CString sId = node->subnodes[i]->GetParam(_T("name"));
		if(!sId.IsEmpty()) mapDT.insert(Str_Long_Pair(sId, 0));		
	}

	// берем все типы документов из базы
	m1 =	ld.AddQuery(_T('e'), 0, m_api->m_doc_mgr.e_dt, 0, true);
	ld.AddQuery(_T('d'), m1, m_api->m_doc_mgr.e_dt, m_api->m_doc_mgr.a_dt_pdt, true);
	ld.LoadEx(true);
	m_api->m_data.GetEntityExtent(m_api->m_doc_mgr.e_dt, aeItems);

	// находим соответствия
	for(i=0; i<aeItems.Size; i++)
	{
		m_api->m_data.GetAttr(aeItems[i], m_api->m_doc_mgr.a_dt_pdt, sId);
		if(sId.IsEmpty()) continue;

		Iter = mapDT.find(sId);
		if(Iter != mapDT.end()) 
			Iter->second = (long)aeItems[i];		
	}

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::XMLGetProducts( CaplXMLNode *node, map<Str_Str_Pair, long> &mapProducts )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!node) return false;

	// переменные
	int i;
	long dID;
	CString sId, sVerId;
	CaplInstance *ciPrd;
	CaplLoadData ld(&m_api->m_data);
	
	map<Str_Str_Pair, long> mapID;
	map<Str_Str_Pair, long>::iterator Iter;

	dID = aplStartWaitDlg(APL_T("Построение ссылок на изделия..."));

	aplExtent aeItems, aeTemp;
	CString sRequestPart, sRequesTotal;
	CString sExtPart, sExtTotal, sSql;

	for(i=0; i<node->subnodes.GetSize(); i++)
	{
		// обозначения
		sId = node->subnodes[i]->GetParam(_T("id"));
		sVerId = node->subnodes[i]->GetParam(_T("product_ver"));

		// готовим мап ( in: (обозначение_изделия, обозначение_версии_изделия), out:(адрес узла xml)
		// примечание адрес узла пока не используется, оставил на всякий случай
		if(sId.IsEmpty() && sVerId.IsEmpty()) continue;
		mapID.insert( pair<Str_Str_Pair, long>( Str_Str_Pair(sId, sVerId), (long)node->subnodes[i] ) );

		// формируем части запрос
		sRequestPart.Format(_T("Ext%d {product_definition_formation(.id='%s' AND .of_product->product.id='%s')}\n"), i, sVerId, sId);
		sRequesTotal += sRequestPart;

		sExtPart.Format(_T("Ext%d OR "), i);
		sExtTotal += sExtPart;
		
		// выполняем запрос
		if(sRequesTotal.GetLength()>1000 || i==(node->subnodes.GetSize()-1))						
		{
			sExtTotal = sExtTotal.Left(sExtTotal.GetLength()-4);
			sSql.Format(_T("SELECT %s FROM %s END_SELECT"), sExtTotal, sRequesTotal);

			if(m_api->m_data.NET_QueryEditParse(sSql, false))
			{
				m_api->m_data.NET_QueryExecute(aeTemp);
				aeItems.Append(aeTemp);
			}

			sRequesTotal.Empty();
			sExtTotal.Empty();
			sSql.Empty();

			aeTemp.Clear();
		}
	}

	// загружаем нужное 
	LoadImportantPdfInfo(aeItems);
	
	// находим соответствия версий изделий
	for(i=0; i<aeItems.Size; i++)
	{
		if(!m_api->m_data.IsKindOf(aeItems[i], m_api->m_prd_mgr.e_pdf)) continue;
		m_api->m_data.GetAttr(aeItems[i], m_api->m_prd_mgr.a_pdf_id, sVerId);

		m_api->m_data.GetAttr(aeItems[i], m_api->m_prd_mgr.a_pdf_prd, ciPrd);
		if(!ciPrd) continue;

		m_api->m_data.GetAttr(ciPrd, m_api->m_prd_mgr.a_prd_id, sId);
		if(sId.IsEmpty()) continue;

		Iter = mapID.find(Str_Str_Pair(sId, sVerId));
		if(Iter == mapID.end()) continue;

		mapProducts.insert( pair<Str_Str_Pair, long>(Str_Str_Pair(sId, sVerId), (long)aeItems[i]) );
	}

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::XMLGetProductInstances( CaplXMLNode *node, map<CString, long> &mapInstances, map<Str_Str_Pair, long> &mapProducts )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!node) return false;

	// переменные
	int i;
	long dID;
	CString sPrdId, sPdfId;
	CaplInstance *ciPdf = 0;
	CaplXMLNode *nodeProduct;
	CaplLoadData ld(&m_api->m_data);

	map<Str_Long_Pair, long> mapID;
	map<Str_Long_Pair, long>::iterator Iter;
	map<Str_Str_Pair, long>::iterator IterPdf;

	dID = aplStartWaitDlg(APL_T("Построение ссылок на экземпляры изделий..."));

	int count = 0;
	aplExtent aeItems, aeTemp;
	CString sRequestPart, sRequesTotal;
	CString sExtPart, sExtTotal, sSql, sSN;

	for(i=0; i<node->subnodes.GetSize(); i++)
	{
		// обозначения
		sSN = node->subnodes[i]->GetParam(_T("serialno"));
		if(sSN.IsEmpty()) continue;

		nodeProduct = node->subnodes[i]->FindSingleNodeBN(_T("PRODUCT_REF"));
		if(!nodeProduct) continue;

		sPrdId = nodeProduct->GetParam(_T("id"));
		sPdfId = nodeProduct->GetParam(_T("ver_id"));
		
		IterPdf = mapProducts.find(Str_Str_Pair(sPrdId, sPdfId));
		if(IterPdf == mapProducts.end()) continue;

		ciPdf = (CaplInstance*)IterPdf->second;
		if(!ciPdf) continue;
		
		// готовим мап
		mapID.insert( pair<Str_Long_Pair, long>( Str_Long_Pair(sSN, (long)ciPdf), (long)node->subnodes[i] ) );
		
		// формируем части запрос
		sRequestPart.Format(_T("Ext%d {apl_product_instance(.serial_number='%s' AND .formation=#%d)}\n"), i, sSN, ciPdf->GetId());
		sRequesTotal += sRequestPart;

		sExtPart.Format(_T("Ext%d OR "), i);
		sExtTotal += sExtPart;

		// выполняем запрос
		if(sRequesTotal.GetLength()>1000 || i==(node->subnodes.GetSize()-1))						
		{
			sExtTotal = sExtTotal.Left(sExtTotal.GetLength()-4);
			sSql.Format(_T("SELECT %s FROM %s END_SELECT"), sExtTotal, sRequesTotal);

			if(m_api->m_data.NET_QueryEditParse(sSql, false))
			{
				m_api->m_data.NET_QueryExecute(aeTemp);
				aeItems.Append(aeTemp);
			}

			sRequesTotal.Empty();
			sExtTotal.Empty();
			sSql.Empty();

			aeTemp.Clear();
		}
	}

	// загружаем нужное 
	LoadImportantPrdInstInfo(aeItems);

	// находим соответствия версий изделий
	for(i=0; i<aeItems.Size; i++)
	{
		if(!m_api->m_data.IsKindOf(aeItems[i], m_api->m_prd_inst_mgr.e_prd_inst)) continue;
		m_api->m_data.GetAttr(aeItems[i], m_api->m_prd_inst_mgr.a_prd_inst_sn, sSN);

		m_api->m_data.GetAttr(aeItems[i], m_api->m_prd_inst_mgr.a_prd_inst_pdf, ciPdf);
		if(!ciPdf) continue;

		Iter = mapID.find(Str_Long_Pair(sSN, (long)ciPdf));
		if(Iter == mapID.end()) continue;
		
		mapInstances.insert( Str_Long_Pair(sSN, (long)aeItems[i]) );
	}

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::LoadImportantPdfInfo(aplExtent &aeItems)
{
	if(!IsReadyForWork()) return false;
	if(!aeItems.Size) return false;

	long dID = aplStartWaitDlg(APL_T("Загрузка атрибутов изделий..."));

	int nCount = 0;
	CaplLoadData ld(&m_api->m_data, DEF_SOURCE);

	// загружаем только нужное
	for(int i=0; i<aeItems.Size; i++) 
	{
		if(!aeItems[i]->GetType()) continue;

		nCount++;
		ld.AddQuery(0, aeItems[i], true);

		if(nCount==m_nItemsPerOneLoad || i==(aeItems.Size-1))
		{
						ld.AddQuery(_T('d'), 0, m_api->m_prd_mgr.e_pdf, m_api->m_prd_mgr.a_pdf_id, true);
			int m1 =	ld.AddQuery(_T('d'), 0, m_api->m_prd_mgr.e_pdf, m_api->m_prd_mgr.a_pdf_prd, true);
						ld.AddQuery(_T('d'), m1, m_api->m_prd_mgr.e_prd, m_api->m_prd_mgr.a_prd_id, true);			

			ld.LoadEx(true, NULL);
			nCount = 0;
		}
	}	

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::LoadImportantPrdInstInfo(aplExtent &aeItems)
{
	if(!IsReadyForWork()) return false;
	if(!aeItems.Size) return false;

	long dID = aplStartWaitDlg(APL_T("Загрузка атрибутов изделий..."));

	int nCount = 0;
	CaplLoadData ld(&m_api->m_data, DEF_SOURCE);

	// загружаем только нужное
	for(int i=0; i<aeItems.Size; i++) 
	{
		if(!aeItems[i]->GetType()) continue;

		nCount++;
		ld.AddQuery(0, aeItems[i], true);

		if(nCount==m_nItemsPerOneLoad || i==(aeItems.Size-1))
		{
			ld.AddQuery(_T('d'), 0, m_api->m_prd_inst_mgr.e_prd_inst, m_api->m_prd_inst_mgr.a_prd_inst_sn, true);
			
			ld.LoadEx(true, NULL);
			nCount = 0;
		}
	}	

	aplEndWaitDlg(dID);
	return true;
}

bool CaplFaultMgr::XMLGetCharactsAndTypes( CaplXMLNode *node, map<CString, long> &mapCharacts, map<CString, long> &mapCharactTypes )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!node) return false;

	// переменные
	long dID;
	int i, m1;
	CString sId;
	aplExtent aeItems;
	CaplLoadData ld(&m_api->m_data);
	map<CString, long>::iterator Iter;

	dID = aplStartWaitDlg(APL_T("Построение ссылок на характеристики..."));

	// берем обозначения всех характеристик из xml 
	for(i=0; i<node->subnodes.GetSize(); i++)
	{
		CString sId = node->subnodes[i]->GetParam(_T("id"));
		if(!sId.IsEmpty()) mapCharacts.insert(Str_Long_Pair(sId, 0));		
	}

	// берем все характеристики из базы
	m1 =	ld.AddQuery(_T('e'), 0, m_api->m_charact_mgr.e_apl_charact, 0, true);
	ld.AddQuery(_T('d'), m1, m_api->m_charact_mgr.e_apl_charact, m_api->m_charact_mgr.a_apl_charact_id, true);
	ld.LoadEx(true);
	m_api->m_data.GetEntityExtent(m_api->m_charact_mgr.e_apl_charact, aeItems);

	// находим соответствия
	for(i=0; i<aeItems.Size; i++)
	{
		m_api->m_data.GetAttr(aeItems[i], m_api->m_charact_mgr.a_apl_charact_id, sId);
		if(sId.IsEmpty()) continue;

		Iter = mapCharacts.find(sId);
		if(Iter != mapCharacts.end()) 
			Iter->second = (long)aeItems[i];		
	}
	aplEndWaitDlg(dID);

	// типы характеристик
	GetCharactTypes(mapCharactTypes);

	return true;
}

bool CaplFaultMgr::GetCharactTypes( map<CString, long> &mapCharactTypes )
{
	// проверки
	if(!IsReadyForWork()) return false;

	// переменные
	int i, m1;
	CString sId;
	aplExtent aeItems;
	CaplLoadData ld(&m_api->m_data);
	
	// берем все типы характеристик из базы
	m1 =	ld.AddQuery(_T('e'), 0, m_api->m_charact_mgr.e_apl_charact_type, 0, true);
	ld.AddQuery(_T('d'), m1, m_api->m_charact_mgr.e_apl_charact_type, m_api->m_charact_mgr.a_apl_charact_type_name, true);
	ld.LoadEx(true);
	m_api->m_data.GetEntityExtent(m_api->m_charact_mgr.e_apl_charact_type, aeItems);

	// формируем мап
	for(i=0; i<aeItems.Size; i++)
	{
		m_api->m_data.GetAttr(aeItems[i], m_api->m_charact_mgr.a_apl_charact_type_name, sId);
		mapCharactTypes.insert(Str_Long_Pair(sId, (long)aeItems[i]));
	}

	return true;
}

bool CaplFaultMgr::XMLImportProductInstances( CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapInstances)
{
	// проверки
	if(!IsReadyForWork()) return false;

	// узел определяющий место обнаружения неисправности
	CaplXMLNode *node = 0, *nodeInstances = GetChildNodeBN(nodeFault, _T("LOCATION"));
	if(!nodeInstances) return false;

	// переменные
	CString sReference, sSN;
	map<CString, long>::iterator Iter;

	node = GetChildNodeBN(nodeInstances, _T("MAIN_PRODUCT"));
	if(node)
	{
		node = GetChildNodeBN(node, _T("PRODUCT_INSTANCE_REF"));
		sSN = node->GetParam(_T("serialno"));
		Iter = mapInstances.find(sSN);

		if(Iter != mapInstances.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_planer, (CaplInstance*)Iter->second);
	}

	node = GetChildNodeBN(nodeInstances, _T("SYSTEM"));
	if(node)
	{
		node = GetChildNodeBN(node, _T("PRODUCT_INSTANCE_REF"));
		sSN = node->GetParam(_T("serialno"));
		Iter = mapInstances.find(sSN);

		if(Iter != mapInstances.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_system, (CaplInstance*)Iter->second);
	}

	node = GetChildNodeBN(nodeInstances, _T("BLOCK"));
	if(node)
	{
		node = GetChildNodeBN(node, _T("PRODUCT_INSTANCE_REF"));
		sSN = node->GetParam(_T("serialno"));
		Iter = mapInstances.find(sSN);

		if(Iter != mapInstances.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_item, (CaplInstance*)Iter->second);
	}

	node = GetChildNodeBN(nodeInstances, _T("ELEMENT"));
	if(node)
	{
		node = GetChildNodeBN(node, _T("PRODUCT_INSTANCE_REF"));
		sSN = node->GetParam(_T("serialno"));
		Iter = mapInstances.find(sSN);

		if(Iter != mapInstances.end())
		{
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_part, (CaplInstance*)Iter->second);
		}
		/*else 
		{
			Iter = mapProducts.find(sReference);
			if(Iter != mapProducts.end())
				m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_part, (CaplInstance*)Iter->second);
		}*/
	}

	return true;
}

bool CaplFaultMgr::XMLImportCharValues( CaplXMLNode *nodeFault, CaplInstance *ciRefusal, 
									   map<CString, long> &mapCharacts, 
									   map<CString, long> &mapCharactTypes,
									   map<CString, long> &mapOrg)
{
	// проверки
	if(!IsReadyForWork()) return false;

	// узел с характеристиками
	CaplXMLNode *nodeCharacts = GetChildNodeBN(nodeFault, _T("CHARACT_VALUES"));
	if(!nodeCharacts) return false;

	// переменные
	CaplXMLNode *nodeCharact = 0;
	map<CString, long>::iterator Iter;
	CString sCharactId, sAssignedTypeName, sValueType, sValue;
	CaplInstance *ciCharVal = 0, *ciCharact = 0, *ciCharactType = 0;

	// импорт занчений характеристик
	for(int i=0 ; i<nodeCharacts->subnodes.GetSize(); i++)
	{
		ciCharact = 0;
		ciCharactType = 0;

		// берем атрибуты
		sCharactId = nodeCharacts->subnodes[i]->GetParam(_T("charact_id"));
		sAssignedTypeName = nodeCharacts->subnodes[i]->GetParam(_T("assigned_type_name"));
		sValueType = nodeCharacts->subnodes[i]->GetParam(_T("data_type"));
		sValue = nodeCharacts->subnodes[i]->GetParam(_T("value"));

		// характеристика
		Iter = mapCharacts.find(sCharactId);
		if(Iter == mapCharacts.end()) continue;
		else ciCharact = (CaplInstance*)Iter->second;

		// тип характеристики
		Iter = mapCharactTypes.find(sAssignedTypeName);
		if(Iter != mapCharactTypes.end()) 
			ciCharactType = (CaplInstance*)Iter->second;;		

		// значение
		if(sValueType == _T("descriptive"))
		{
			m_api->m_charact_mgr.CreateDescriptiveCharacteristic(ciRefusal, ciCharact, ciCharactType, sValue);
		}
		else if(sValueType == _T("measure"))
		{
			m_api->m_charact_mgr.CreateMeasuredCharacteristic(ciRefusal, ciCharact, ciCharactType, __atof(sValue), 0, 0);
		}
		else if(sValueType == _T("monet"))
		{
			m_api->m_charact_mgr.CreateMonetaryCharacteristic(ciRefusal, ciCharact, ciCharactType, __atof(sValue));
		}
		else if(sValueType == _T("organization"))
		{
			Iter = mapOrg.find(sValue);
			if(Iter == mapOrg.end()) continue;
			if(Iter->second == 0) continue;

			m_api->m_charact_mgr.CreateReferenceCharacteristic(ciRefusal, ciCharact, ciCharactType, (CaplInstance*)Iter->second);
		}
		else if(sValueType == _T("time"))
		{
			m_api->m_charact_mgr.CreateDateTimeCharacteristic(ciRefusal, ciCharact, ciCharactType, sValue);
		}						
	}

	return true;
}

bool CaplFaultMgr::XMLImprotDocuments( CaplXMLNode *nodeFault, CaplInstance *ciRefusal, 
									  map<CString, long> &mapDocTypes, 
									  map<CString, long> &mapDocument )
{
	// проверки
	if(!IsReadyForWork()) return false;

	// узел с документами
	CaplXMLNode *nodeDocuments = GetChildNodeBN(nodeFault, _T("DOCUMENTS"));
	if(!nodeDocuments) return false;

	// переменные
	CString sInclude, sRefGuid;
	CString sId, sName, sDescr, sPath, sDocType;
	CString sAuthentic, sAddCode, sDependDesp;
	CaplInstance *ciType, *ciRevision;
	map<CString, long>::iterator Iter;
	CaplXMLNode *nodeRevision = 0;

	CString sVerId, sVerLabel, sVerDescr, sVerFormat, sVerSheets, sVerTotalSheets;

	// импорт документов
	for(int i=0 ; i<nodeDocuments->subnodes.GetSize(); i++)
	{
		sVerId.Empty(); sVerLabel.Empty(); sVerDescr.Empty(); 
		sVerFormat.Empty(); sVerSheets.Empty(); sVerTotalSheets.Empty();

		// атрибуты документа
		sId = nodeDocuments->subnodes[i]->GetParam(_T("id"));
		sName = nodeDocuments->subnodes[i]->GetParam(_T("name"));
		sDescr = nodeDocuments->subnodes[i]->GetParam(_T("description"));
		sAuthentic = nodeDocuments->subnodes[i]->GetParam(_T("authentic"));
		sAddCode = nodeDocuments->subnodes[i]->GetParam(_T("add_code"));
		sDependDesp = nodeDocuments->subnodes[i]->GetParam(_T("depend_desp"));
		sInclude = nodeDocuments->subnodes[i]->GetParam(_T("include_in_doc"));
		sDocType = nodeDocuments->subnodes[i]->GetParam(_T("doc_type_name"));

		// атрибуты версии
		nodeRevision = nodeDocuments->subnodes[i]->FindSingleNodeBN(_T("REVISION"));
		if(nodeRevision)
		{
			sVerId = nodeRevision->GetParam(_T("id"));
			sVerLabel = nodeRevision->GetParam(_T("label"));
			sVerDescr = nodeRevision->GetParam(_T("description"));
			sVerFormat = nodeRevision->GetParam(_T("format"));
			sVerSheets = nodeRevision->GetParam(_T("sheets"));
			sVerTotalSheets = nodeRevision->GetParam(_T("total_sheets"));
		}

		// узнаем тип документа
		Iter = mapDocTypes.find(sDocType);
		if(Iter != mapDocTypes.end()) ciType = (CaplInstance*)Iter->second;
		else ciType = 0;

		// создаем временный документ на диске
		sPath = CreateTemproryFileFromNode(nodeRevision->FindSingleNodeBN(_T("FILE")));
		if(sPath.IsEmpty()) continue;

		// сначала пытаемся найти такой же документ
		// Проверка уникальности обозначения
		aplExtent aeOut;
		CaplInstance *ciDoc = 0;
		CaplAttrValue tst_values[4];

		tst_values[0].value.Set(sId);
		tst_values[0].attr=m_api->m_doc_mgr.a_doc_id;

		tst_values[1].value.Set(ciType);
		tst_values[1].attr=m_api->m_doc_mgr.a_doc_kind;

		tst_values[2].value.Set(sAddCode);
		tst_values[2].attr=m_api->m_doc_mgr.a_doc_add_dt_code;

		tst_values[3].value.Set(sDependDesp);
		tst_values[3].attr=m_api->m_doc_mgr.a_doc_code_depend_desp;

		m_api->m_data.NET_FindInstancesWithAttrValues(m_api->m_doc_mgr.e_doc, 4, &tst_values[0], aeOut, true);
		if(aeOut.Size == 1) 
		{
			ciDoc = aeOut[0];
			m_api->m_doc_mgr.CreateAssociation(ciRefusal, ciDoc);
		}
		else if(aeOut.Size > 1)
		{
			MessageBox(0, APL_T("В базе данных найдены повторяющися документы!"), APL_T("Предупреждение"), MB_ICONSTOP);
		}

		// создаем в базе документ
		if(!ciDoc)
			ciDoc = m_api->m_doc_mgr.CreateDocument(sId, sName, sDescr, ciType, sPath, true, ciRefusal);

		if(ciDoc)
		{
			// дополнительные атрибуты документа
			m_api->m_data.PutAttr(ciDoc, m_api->m_doc_mgr.a_doc_authentic, (sAuthentic==_T("1")?true:false));
			m_api->m_data.PutAttr(ciDoc, m_api->m_doc_mgr.a_doc_add_dt_code, sAddCode);
			m_api->m_data.PutAttr(ciDoc, m_api->m_doc_mgr.a_doc_code_depend_desp, sDependDesp);
			m_api->m_data.PutAttr(ciDoc, m_api->m_doc_mgr.a_doc_incl_in_doc, (sInclude==_T("1")?true:false));

			// дополнительные атрибуты версии документа
			m_api->m_data.GetAttr(ciDoc, m_api->m_doc_mgr.a_apl_doc_active, ciRevision);
			if(ciRevision)
			{
				m_api->m_data.PutAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_id, sVerId);
				m_api->m_data.PutAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_label, sVerLabel);
				m_api->m_data.PutAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_descr, sVerDescr);
				m_api->m_data.PutAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_format, sVerFormat);
				m_api->m_data.PutAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_sheets, sVerSheets);
				m_api->m_data.PutAttr(ciRevision, m_api->m_doc_mgr.a_apl_doc_rev_total_sheets, sVerTotalSheets);				
			}

			// ссылка на новый документ
			sRefGuid = nodeDocuments->subnodes[i]->GetParam(_T("id"));
			if(!sRefGuid.IsEmpty()) mapDocument.insert(Str_Long_Pair(sRefGuid, (long)ciDoc));
		}

		::DeleteFile(sPath);
	}

	return true;
}

CString CaplFaultMgr::CreateTemproryFileFromNode(CaplXMLNode *nodeFile)
{
	if(!nodeFile) return _T("");
	CString sContent, sName, sPath;

	// атрибуты изображения
	sContent = nodeFile->GetParam(_T("content"));
	if(sContent.IsEmpty()) return _T("");

	sName = nodeFile->GetParam(_T("file"));
	GetFileNameFromPath(sName);

	// копируем на диск
	sContent = DecodeFromBase64(sContent);
	sPath = CreateTemproryFileByContent(sName, sContent);
	
	return sPath;
}

bool CaplFaultMgr::XMLImportPictures( CaplXMLNode *nodeFault, CaplInstance *ciRefusal )
{
	// проверки
	if(!IsReadyForWork()) return false;

	// узел с изображениями
	CaplXMLNode *nodePictures = GetChildNodeBN(nodeFault, _T("PICTURES"));
	if(!nodePictures) return false;

	// переменные
	aplExtent aePictures;
	CaplInstance *ciPicture = 0;
	CString sContent, sPath, sName;
	CaplXMLNode *nodeFile = 0, *nodePicture = 0;

	// импорт изображений
	for(int i=0 ; i<nodePictures->subnodes.GetSize(); i++)
	{
		// узел с изображением
		nodeFile = GetChildNodeBN(nodePictures->subnodes[i], _T("FILE"));
		if(!nodeFile) continue;

		sPath = CreateTemproryFileFromNode(nodeFile);
		if(sPath.IsEmpty()) continue;
		
		// создаем запись в базе
		ciPicture = m_api->m_doc_mgr.CreateFile(sPath);
		::DeleteFile(sPath);
		if(!ciPicture) continue;

		aePictures.Add(ciPicture);
	}

	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_files, aePictures);
	return true;
}

CString CaplFaultMgr::CreateTemproryFileByContent( CString name, CString sContent )
{
	CFile file;
	CString sPath; sPath.GetEnvironmentVariable(_T("temp"));  sPath+= name;
	
	if(!file.Open(sPath, CFile::modeCreate|CFile::modeWrite)) return _T("");
	file.Write(sContent, sContent.GetLength());

	return sPath;
}

bool CaplFaultMgr::GetFileNameFromPath( CString &path )
{
	if(path.IsEmpty()) return false;

	int nIndex = path.ReverseFind(_T('\\'));
	if(nIndex == -1) return false;

	path = path.Right( path.GetLength() - nIndex - 1 );
	return true;
}

bool CaplFaultMgr::XMLImprotStringAttrs( CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapDocument )
{
	CString strParam;
	map<CString, long>::iterator Iter;

	// родительская неисправность +
	// это делается чуть позжее

	// собственный guid +
	nodeFault->GetParam(_T("id"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_guid, strParam);
	
	// состояние +
	nodeFault->GetParam(_T("state"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_state, strParam);
	
	// описание +
	nodeFault->GetParam(_T("notes"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_description, strParam);
	
	// тип документа +
	nodeFault->GetParam(_T("document_type"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_type, strParam);
	
	// номер документа +
	nodeFault->GetParam(_T("document_num"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_num, strParam);
	
	// дата оформления документа +
	nodeFault->GetParam(_T("document_date"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_doc_date, strParam);
	
	// дата обнаружения +
	nodeFault->GetParam(_T("detection_date_time"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_date_detection, strParam);
	
	// дата устранения +
	nodeFault->GetParam(_T("recovery_date_time"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_date_removal, strParam);
	
	// внешний вид (состояние) +
	nodeFault->GetParam(_T("external_view"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_ext_view, strParam);
	
	// внешнее проявление (строкой) +
	nodeFault->GetParam(_T("manifistation_string"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_manifestation_str, strParam);
	
	// резултаты исследования +
	nodeFault->GetParam(_T("commission_conclusion"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_result, strParam);
	
	// необходимые мероприятия +
	nodeFault->GetParam(_T("necassary_arrangments"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_necassary_arrangm, strParam);
	
	// номер акта исследования +
	nodeFault->GetParam(_T("research_act_num"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_str, strParam);
	
	// дата оформления акта исследования +
	nodeFault->GetParam(_T("research_act_date"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_date, strParam);
	
	// принятые меры +
	nodeFault->GetParam(_T("actions"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_accepted_arrangements_str, strParam);
	
	// сведения об устраенении +
	nodeFault->GetParam(_T("dispose_data"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_dispose_data, strParam);
	
	// итоговое решение (решение комиссии) +
	nodeFault->GetParam(_T("result_dicision"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_result_decision, strParam);
	
	// номер рекламационного акта +
	nodeFault->GetParam(_T("reclamation_report"), strParam);
	m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_document_str, strParam);
	
	// ссылка на документ "Акт исследования" +
	nodeFault->GetParam(_T("research_act"), strParam);
	Iter = mapDocument.find(strParam);
	if(Iter != mapDocument.end())
		m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_act_obj, (CaplInstance*)Iter->second);
	
	// ссылка на документ "Рекламационный акт" + 
	nodeFault->GetParam(_T("reclamation_act"), strParam);
	Iter = mapDocument.find(strParam);
	if(Iter != mapDocument.end())
		m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_document_obj, (CaplInstance*)Iter->second);	

	return true;
}

bool CaplFaultMgr::XMLImprotLots( CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapLots )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!nodeFault) return false;

	CString strParam;
	map<CString, long>::iterator Iter;

	strParam = nodeFault->GetParam(_T("element_lot"));
	if(!strParam.IsEmpty())
	{
		Iter = mapLots.find(strParam);
		if(Iter != mapLots.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_part_lot, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("block_lot"));
	if(!strParam.IsEmpty())
	{
		Iter = mapLots.find(strParam);
		if(Iter != mapLots.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_item_lot, (CaplInstance*)Iter->second);
	}

	return true;
}

bool CaplFaultMgr::XMLImprotOrganizations( CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapOrg )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!nodeFault) return false;

	CString strParam;
	map<CString, long>::iterator Iter;

	strParam = nodeFault->GetParam(_T("failure_cause_originator"));
	if(!strParam.IsEmpty())
	{
		Iter = mapOrg.find(strParam);
		if(Iter != mapOrg.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_culprit, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("workshop"));
	if(!strParam.IsEmpty())
	{
		Iter = mapOrg.find(strParam);
		if(Iter != mapOrg.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_org, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("sector"));
	if(!strParam.IsEmpty())
	{
		Iter = mapOrg.find(strParam);
		if(Iter != mapOrg.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_sector, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("research_lab"));
	if(!strParam.IsEmpty())
	{
		Iter = mapOrg.find(strParam);
		if(Iter != mapOrg.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_lab, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("research_workshop"));
	if(!strParam.IsEmpty())
	{
		Iter = mapOrg.find(strParam);
		if(Iter != mapOrg.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_research_sector, (CaplInstance*)Iter->second);
	}

	return true;
}

bool CaplFaultMgr::XMLImprotClassifierLevels( CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapClassifierLevels )
{
	// проверки
	if(!IsReadyForWork()) return false;
	if(!nodeFault) return false;

	CString strParam;
	map<CString, long>::iterator Iter;

	strParam = nodeFault->GetParam(_T("failure_mode"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_type, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("failure_stage"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_stage, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("detection_context"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_conditions, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("symptom"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_manifestation, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("nature"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_dof, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("reason"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_faultreason, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("recovery_method"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_method, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("effect"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_consequences, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("test_deduction"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_test_deduction, (CaplInstance*)Iter->second);
	}

	strParam = nodeFault->GetParam(_T("culprit_deduction"));
	if(!strParam.IsEmpty())
	{
		Iter = mapClassifierLevels.find(strParam);
		if(Iter != mapClassifierLevels.end())
			m_api->m_data.PutAttr(ciRefusal, m_ExplMgr->a_apl_refusal_culprit_deduction, (CaplInstance*)Iter->second);
	}

	return true;
}

CString CaplFaultMgr::NullTimeInDate( CString time )
{
	if(time.IsEmpty()) return _T("");

	time.Delete( time.GetLength()-6, 6 );
	time += _T("000000");

	return time;
}

//********************************************************************************************
bool CaplFaultMgr::IsPlaner(CaplInstance *PrdInst)
{
	//aplEMErrorClear;
	if(m_api==NULL) return false;
	if(!m_api->m_data.IsDictLoad())  return false;
	if(PrdInst==NULL)  return false;
	if(PrdInst->GetAccessmode()>aplRO)   return false;
	if(PrdInst->GetType()==NULL)  return false;
	if(m_api->m_data.IsKindOf(PrdInst, m_api->m_prd_inst_mgr.e_prd_inst))
	{
		CaplInstance *pdf;
		aplExtent planers;
		if(!GetParentPdfs(planers)) return false;

		if(PrdInst->GetAccessmode()>aplRO) return false;

		if(PrdInst->attrs==NULL)
			m_api->m_prd_inst_mgr.LoadPrdInstInfo(PrdInst);

		m_api->m_data.GetAttr(PrdInst, m_api->m_prd_inst_mgr.a_prd_inst_pdf, pdf);
		if(planers.Find(pdf)>-1) return true;
	}
	else if(m_api->m_data.IsKindOf(PrdInst, m_api->m_prd_mgr.e_pdf))
	{
		aplExtent planers;
		if(!GetParentPdfs(planers)) return false;
		if(planers.Find(PrdInst)>-1) return true;
	}

	return false;
}


/************************************************************************/
bool CaplFaultMgr::GetParentPdfs(aplExtent &ext)
{
	ext.Clear();
	if(m_api == NULL)  return false;
	if(!m_api->m_data.IsDictLoad()) return false;

	int i;
	int cnt_names;
	CString key_name;
	CaplInstance* tmp;
	m_api->m_options_mgr.GetOptionValueBN(APL_STR_LOGBOOK_PARENT_CONFIGURATION_COUNT, cnt_names, 0);
	for(i=0; i<cnt_names; i++)
	{
		key_name.Format(_T("%s_%d"), APL_STR_LOGBOOK_PARENT_CONFIGURATION, i+1);
		m_api->m_options_mgr.GetOptionValueBN(key_name, &tmp, (CaplInstance*)NULL);
		if(tmp!=NULL)
			ext.Add(tmp);
	}

	if(m_api->m_data.IsConnected())
	{
		CaplLoadData ld(&m_api->m_data, DEF_SOURCE);
		bool bLoad = false;

		for(i=0; i<ext.GetSize(); i++)
		{
			if(ext[i]==NULL) continue;
			if(ext[i]->attrs!=NULL) continue;

			ld.AddQuery(0, ext[i], true);
			bLoad = true;
		}
		if(bLoad)
		{
			ld.AddQuery(_T('d'), 0, 0, m_api->m_prd_mgr.a_pdf_prd, true, true);
			ld.LoadEx();
		}
	}

	return true;
}



/************************************************************************/
bool CaplFaultMgr::GetPlanerName(CaplInstance *Planer, CString& name)
{
	/*aplEMErrorClear;
	if(m_api==NULL) aplEMErrorAPI(false);
	if(!m_api->m_data.IsDictLoad()) aplEMErrorConnect(false);

	return m_ShowName.GetName(Planer, name);*/

	return m_api->m_prd_mgr.GetItemName(Planer,name);
}

bool CaplFaultMgr::GetSystemName(CaplInstance *System, CString& name)
{
	/*aplEMErrorClear;
	if(m_api==NULL) aplEMErrorAPI(false);
	if(!m_api->m_data.IsDictLoad()) aplEMErrorConnect(false);

	if(0==System){name=_T(""); return false;}
	if(System->IsDeleted()){name=APL_T("<Удалено>"); return false;}
	if(System->GetAccessmode()>aplRO){name=APL_T("<Нет доступа>"); return false;}

	return m_ShowName.GetName(System, name);*/

	return m_api->m_prd_mgr.GetItemName(System,name);
}

bool CaplFaultMgr::GetPKIName(CaplInstance *pki, CString& name)
{
	/*aplEMErrorClear;

	if(0==pki){name=_T(""); return false;}
	if(pki->IsDeleted()){name=APL_T("<Удалено>"); return false;}
	if(pki->GetAccessmode()>aplRO){name=APL_T("<Нет доступа>"); return false;}

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

	return m_ShowName.GetName(pki, name);*/

	return m_api->m_prd_mgr.GetItemName(pki,name);
}

/************************************************************************/
/************************************************************************/
bool CaplFaultMgr::IsChildItem(CaplInstance* Item, CaplInstance* Parent, bool bFromBase)
{

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

	if(Item==NULL) return false;
	if(Parent==NULL) return false;
	if(Item->GetType()==NULL) return false;
	if(Parent->GetType()==NULL) return false;
	if(Item->GetAccessmode()>aplRO) return false;
	if(Parent->GetAccessmode()>aplRO) return false;

	if(Parent==Item) return true;

	return true;

	/*
	//если Item и Parent - prd_inst
	if(m_api->m_data.IsKindOf(Item, m_api->m_prd_inst_mgr.e_prd_inst) && m_api->m_data.IsKindOf(Parent, m_api->m_prd_inst_mgr.e_prd_inst))
	{
		//здесь все просто актуальная связь только одна
		CaplInstance *rel, *inst = Item, *tst;
		do
		{
			rel = FindActualRelation(inst, NULL, bFromBase);
			if(rel==NULL) return false;
			m_api->m_data.GetAttr(rel, m_api->m_prd_inst_mgr.a_prd_inst_rel_relating, tst);
			if(tst==Parent)
				return true;
			inst = tst;
		} while(1);
	}
	else if(m_api->m_data.IsKindOf(Item, m_api->m_prd_mgr.e_pdf) && m_api->m_data.IsKindOf(Parent, m_api->m_prd_mgr.e_pdf))
	{

		APL_BEFOR_RUN_SQL;
		SaplSQLError err;
		SaplSQLResult res;
		CString sSQL, sResSQL;

		res.type = aplINTEGER;
		res.field = _T("");
		sSQL.Format(_T("begin IsChildItem(%d, %d); end;"), Item->GetId(), Parent->GetId());
		sResSQL = _T("select instance_id from findextemprary where extent_name = 'result'");
		m_api->m_data.NET_RunSql(sResSQL, &res, 1, &err, APL_IN_RUNSQL, NULL, sSQL);
		if(res.values.Size>0)
		{
			int val;
			res.values[0]->Get(val);
			return val>0;
		}
		//используем рекурсию
		int i;
		aplExtent rels, ext;
		m_api->m_prd_mgr.WhereUsedProduct(Item, rels, ext);
		for(i=0; i<ext.GetSize(); i++)
		{
			if(ext[i]==Parent)
				return true;
			else if(IsChildItem(ext[i], Parent))
				return true;
		}
	}
	*/

	return false;
}



