// AshMoImportDialog.cpp : implementation file
//

#include "stdafx.h"

//#define ENABLE_ASH_MO 

#ifdef ENABLE_ASH_MO

#include "resource.h"
#include "PSM.h"
#include "AshMoImportDialog.h"


void WriteAshMoDBLog(CaplAPI *m_api,LPCTSTR txt)
{
	if(0==m_api) return;
	if(!m_api->m_data.IsConnected()) return;
	m_api->m_data.NET_WriteLog(_T("ASH-MO.log"), txt, false);
}

// Ищет в БД папку по имени без учета иерархии папок (в любом месте)
CaplInstance *FindFolderByName(LPCTSTR name , CaplAPI *m_api )
{
	CaplAttrValue tst_value;
	aplExtent ext;
	tst_value.value.Set((LPTSTR)name);
	tst_value.attr=m_api->m_folder_mgr.a_folder_name;
	m_api->m_data.NET_FindInstancesWithAttrValues(m_api->m_folder_mgr.e_folder,1,&tst_value,ext,false);
	
	if(0==ext.GetSize()) return 0;
	CaplInstance *folder=ext[0];
	m_api->m_folder_mgr.LoadFolderInfo(folder);
	return folder;
}

CString FindSubstrInStrMap(CaplStrStrMap &strmap,LPCTSTR str)
{
	if(0==str) return _T("");
	if(_T('\0')==str[0]) return _T("");

	int i;
	for(i=0;i<strmap.GetSize();i++)
	{
		CaplStrStrMap::CaplStrStrMapItem *item=strmap.GetAt(i);
		if(item->str.Find(str)>=0) return item->val;
	}
	return _T("");
}


//*******************************************************************************************************

bool bFindSignFilesForPackage(LPCTSTR sPackageFullPath, CStringArray &saSignFiles)
{
	saSignFiles.RemoveAll();
	if(0==sPackageFullPath) return false;
	if(_T('\0')==sPackageFullPath[0]) return false;

	CStringArray sSignExtentions; 
	sSignExtentions.Add(_T("*.sign"));
	sSignExtentions.Add(_T("*.sig"));
	sSignExtentions.Add(_T("*.p7s"));

	CString sMask0, sPackagePath=sPackageFullPath;
	int i=sPackagePath.ReverseFind(_T('.'));

	if(i>0) sMask0=sPackagePath.Left(i);
	else sMask0=sPackagePath;

	CFileFind ff;

	for(i=0;i<sSignExtentions.GetSize();i++)
	{
	  BOOL bFind = ff.FindFile(sMask0+sSignExtentions[i]);
	  while(bFind)
	  {
		  bFind = ff.FindNextFile();
		  saSignFiles.Add(ff.GetFilePath());
	  }
	}
	return true;
}

//*******************************************************************************************************

bool str2strArry(CString &str, CStringArray &sa)
{
	sa.RemoveAll();
	if(str==_T("")) return true;

	CString sLine;
	int i=0,j=0;
	while(true)
	{
	  j=str.Find(_T('\n'),i);
	  if(j>0) sLine=str.Mid(i,j-i);
	  else sLine=str.Right(str.GetLength()-i);

	  sLine.TrimLeft(); sLine.TrimRight();
	  if(sLine!=_T("")) sa.Add(sLine);
	  if(j<0) break;

	  i=j+sizeof(_T('\n'));
	}
	return true;
};

//*******************************************************************************************************
// Одноразовая функция для закрузки ЕКПС в виде справочника
/* bool LoadEKPS(CaplAPI &m_api)
{
	//if(!m_api.m_data.IsConnected()){AfxMessageBox(_T("Соединение с БД не установлено!"),MB_ICONSTOP|MB_OK); return false;}

	CaplStringFile strFile;

	if(!strFile.Open(_T("C:\\_____ASH\\ekps.txt"),CFile::modeRead, aplANSI)) {AfxMessageBox(_T("Ошибка открытия файла!"),MB_ICONSTOP|MB_OK); return false;}

	int i,j;
	CaplInstance *instLastClass=0;
	CaplInstance *instLastGroup=0;
	CString sLine,sType,sId,sName,sDescr;

	CaplInstance *instSystem=m_api.m_classifier_mgr.GetClassifierSystemById(_T("ЕКПС"));
	if(0!=instSystem){AfxMessageBox(_T("Справочник ЕКПС уже существует! Повторная загрузка невозможна!"),MB_ICONSTOP|MB_OK); return false;}

	instSystem=m_api.m_classifier_mgr.CreateClassifierSystem(0,_T("ЕКПС"),_T("Единый кодификатор предметов снабжения"));
	if(0==instSystem){AfxMessageBox(_T("Ошибка создания справочника!"),MB_ICONSTOP|MB_OK); return false;}

	while(true)
	{
		if(!strFile.ReadString(sLine)) break;  // файл кончился
		sLine.TrimLeft(); sLine.TrimRight();

		if(sLine==_T("")) continue;

		bool isKlass=false;

		i=sLine.Find(_T(' '));
		if(i>0)
		{
			sType=sLine.Left(i);
			if(sType==_T("Группа") || sType==_T("Класс"))
			{
				isKlass=true;
				if(0!=instLastClass && sDescr!=_T("")) m_api.m_data.PutAttr(instLastClass,m_api.m_classifier_mgr.a_apl_classifier_level_descr,sDescr);
				sDescr=_T("");

				i++;
				while(sLine[i]==_T(' ')) i++;
				j=sLine.Find(_T(' '),i);
				sId=sLine.Mid(i,j-i);

				i=j+1;
				while(sLine[i]==_T(' ')) i++;

				sName=sLine.Right(sLine.GetLength()-i);

				// Создаем уровень классификации
				CaplInstance *instParent=instLastGroup;
				if(sType==_T("Группа")) instParent=0;

				instLastClass=m_api.m_classifier_mgr.CreateClassifierLevel(instSystem,instParent,sId,sName,_T(""),0,false);
				if(sType==_T("Группа")) instLastGroup= instLastClass;
			}
		}
		if(!isKlass) 
		{
			if(sDescr!=_T("")) sDescr+=_T("\n");
			sDescr += sLine;
		}
	}
	if(0!=instLastClass && sDescr!=_T("")) m_api.m_data.PutAttr(instLastClass,m_api.m_classifier_mgr.a_apl_classifier_level_descr,sDescr);
	sDescr=_T("");

	m_api.SaveChanges();
	strFile.Close();

	AfxMessageBox(_T("Готово!"));

	return true;
}*/




// CAshMoImportDialog dialog

IMPLEMENT_DYNAMIC(CAshMoImportDialog, CaplResizableDialog)

CAshMoImportDialog::CAshMoImportDialog(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CAshMoImportDialog::IDD, pParent)
{

	m_instEkpsSystem=0;
	m_bOnlyVerify=false;
}

CAshMoImportDialog::~CAshMoImportDialog()
{
}

void CAshMoImportDialog::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LOG, m_log_ctrl);
	DDX_Control(pDX, IDCANCEL, m_cancel_btn);
	DDX_Control(pDX, IDC_START, m_start_btn);
	DDX_Control(pDX, IDC_USE_DIG_SIGN, m_use_dig_sign);
}


BEGIN_MESSAGE_MAP(CAshMoImportDialog, CaplResizableDialog)

	ON_BN_CLICKED(IDC_START, &CAshMoImportDialog::OnBnClickedStart)
END_MESSAGE_MAP()


// CAshMoImportDialog message handlers

BOOL CAshMoImportDialog::OnInitDialog()
{
	CaplResizableDialog::OnInitDialog();

	// TODO:  Add extra initialization here
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);
	AddAnchor(IDC_START,BOTTOM_LEFT);
	AddAnchor(IDC_USE_DIG_SIGN,BOTTOM_LEFT);
	AddAnchor(IDC_LOG,TOP_LEFT,BOTTOM_RIGHT);
	

	m_cancel_btn.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_cancel_btn.SetFlat(FALSE);
	m_start_btn.SetIcon(GetAplStdIco16(APLSTDICO_PLAY));
	m_start_btn.SetFlat(FALSE);

	m_use_dig_sign.SetCheck(AfxGetApp()->GetProfileInt(_T("ASH_MO"),_T("USE_DIG_SIGN"), 1));

	if(m_bOnlyVerify)
	{
		SetWindowText(_T("АСХ МО - Прием и проверка целостности пакета ЭКД"));
		m_use_dig_sign.ShowWindow(SW_HIDE);
		m_start_btn.SetWindowText(_T("Проверить"));
		m_start_btn.SetIcon(GetAplTableIco(APL_TABLE_OPEN));
	}

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

void CAshMoImportDialog::OnCancel()
{
	AfxGetApp()->WriteProfileInt(_T("ASH_MO"),_T("USE_DIG_SIGN"), m_use_dig_sign.GetCheck());
	CaplResizableDialog::OnCancel();
}



void CAshMoImportDialog::AddLog(LPCTSTR txt, int bShowMsg)
{
	if(0==txt) return;
	if(_T('\0')==txt[0]) return;
	m_log_ctrl.SetSel(-1,-1);
	m_log_ctrl.ReplaceSel(_T("\r\n"));
	m_log_ctrl.SetSel(-1,-1);
	CString buf=txt;
	buf.Replace(_T("\n"),_T("\r\n"));
	m_log_ctrl.ReplaceSel(buf);
	if(0==bShowMsg) return;
	AfxMessageBox(txt,bShowMsg);
}
//*******************************************************************************************
bool CAshMoImportDialog::Init()
{
	if(0==m_api) return false;
	if(!m_api->m_data.IsConnected()){AfxMessageBox(_T("Соединение с БД не установлено!"),MB_ICONSTOP|MB_OK); return false;}
	if(0==m_api->m_appr_mgr.GetCurrentPerson()){AfxMessageBox(_T("Анонимный пользователь не может загружать пакеты!"),MB_ICONSTOP|MB_OK); return false;}

	CString sRarPath=_T("C:\\Program Files\\WinRAR\\winrar.exe");
	if(!CaplFile::IsFileExist(sRarPath))
	{
		sRarPath=_T("C:\\Program Files (x86)\\WinRAR\\winrar.exe");
		if(!CaplFile::IsFileExist(sRarPath)){AfxMessageBox(_T("WinRar не найден! Работа невозможна!"),MB_ICONSTOP|MB_OK); return false;}
	}
	m_sRarPath=sRarPath;

	m_api->m_classifier_mgr.LoadDictionary();
	m_instEkpsSystem=m_api->m_classifier_mgr.GetClassifierSystemById(_T("ЕКПС"));
	if(0==m_instEkpsSystem){AfxMessageBox(_T("Справочник ЕКПС отсутствует в БД! Загрузка невозможна!"),MB_ICONSTOP|MB_OK); return false;}

	m_api->m_classifier_mgr.LoadClassifierInfo(m_instEkpsSystem);

	return true;
}
//*******************************************************************************************
void CAshMoImportDialog::OnBnClickedStart()
{
	AshMoImportPackage();
}
//*******************************************************************************************

bool CAshMoImportDialog::AshMoImportPackage()
{
	if(0==m_api) return false;
	if(m_sRarPath==_T(""))  return false;
	if(0==m_instEkpsSystem) return false;

	m_log_ctrl.SetWindowText(_T(""));

	CString sLog;
	m_sTempPath.GetEnvironmentVariable(_T("TEMP"));
	if(m_sTempPath[m_sTempPath.GetLength()]!=_T('\\')) m_sTempPath+=_T('\\');
	m_sTempPath+=_T("ASH_MO\\");
	CreateDirectory(m_sTempPath,NULL);

	CFileDialog f_dlg(TRUE,_T("*.rar"),0,OFN_HIDEREADONLY, APL_T("Файлы архивов (*.rar)|*.rar|Все файлы (*.*)|*.*|"),0);
	if(f_dlg.DoModal()!=IDOK) return false;
	CString sPackagePath=f_dlg.GetPathName();
	//CString sPackagePath=_T("C:\\_____ASH\\Package_000000_01.rar");

	sLog=_T("\nВыбран пакет:")+sPackagePath;
	AddLog(sLog); 

		
	CString sPackageName,sPackageFile;	
	int i,j;
	i=sPackagePath.ReverseFind(_T('\\'));
	j=sPackagePath.ReverseFind(_T('.'));

	if(i>=0 && i<=i) sPackageName=sPackagePath.Mid(i+1,j-(i+1));
	if(sPackageName==_T("")){AddLog(_T("Некорректное имя пакета! Работа невозможна!"),MB_ICONSTOP|MB_OK); return false;}

	i=sPackagePath.ReverseFind(_T('\\'));
	if(i>=0) sPackageFile= sPackagePath.Right(sPackagePath.GetLength()-(i+1));
	else sPackageFile= sPackagePath;


	CString sReqFileName=sPackageName+_T(".requisite");

	//sReqFileName="Package_000_01.requisite";

	CString sReqFilePath=m_sTempPath+sReqFileName;
	if(CaplFile::IsFileExist(sReqFilePath))
	{
		::SetFileAttributes(sReqFilePath, FILE_ATTRIBUTE_NORMAL);
		::DeleteFile(sReqFilePath);
		if(CaplFile::IsFileExist(sReqFilePath)){AddLog(_T("Ошибка удаления старого файла реквизитов! Работа невозможна!"),MB_ICONSTOP|MB_OK); return false;}
	}

	long res;
	CString sCmd;

	// Проверка файлов в архиве
	AddLog(_T("Проверка файла архива... "));

	ULONGLONG flen=0x80000000;
	CFile file;
	if(file.Open(sPackagePath,CFile::modeRead))
	{
		flen=file.GetLength();
		file.Close();
	}
	
	if(flen<(100*1024*1024))  // Файлы более 100 Мб не проверяем, т.к. долго
	{
		sCmd.Format(_T("\"%s\" t -r \"%s\""),m_sRarPath,sPackagePath);
		res=aplCreateProcess(0,sCmd,true);
		if(0!=res)
		{
			AddLog(_T("Файл архива поврежден!"),MB_ICONSTOP|MB_OK);
			GenerateUveoml(false,sPackageFile, _T(""), _T(""), _T(""),_T("Файл архива поврежден!"));
			return false;
		}
	}

	AddLog(_T("Файл архива корректен.\n"));

	// Чтение файла реквизитов пакета

	AddLog(_T("Извлечение файла реквизитов... "));

	sCmd.Format(_T("\"%s\" e \"%s\" \"%s\" \"%s\""),m_sRarPath,sPackagePath,sReqFileName, m_sTempPath);

	res=aplCreateProcess(0,sCmd,true);

	if(0!=res)
	{
		AddLog(_T("В архиве не найден файл реквизитов пакета!"),MB_ICONSTOP|MB_OK); 
		GenerateUveoml(false,sPackageFile, _T(""), _T(""), _T(""),_T("В архиве не найден файл реквизитов пакета!"));
		return false;
	}
	if(!CaplFile::IsFileExist(sReqFilePath))
	{
		AddLog(_T("Ошибка извлечения файла реквизитов пакета!"),MB_ICONSTOP|MB_OK); 
		GenerateUveoml(false,sPackageFile, _T(""), _T(""), _T(""),_T("Ошибка при извлечении файла реквизитов пакета!"));
		return false;
	}


	AddLog(_T("Файл реквизитов получен.\n"));

	CaplStrStrMap mapRequsite;
	if(!CaplDocManager::LoadRequisiteFromFile(sReqFilePath,mapRequsite))
	{
		AddLog(_T("Ошибка обработки файла реквизитов!"),MB_OK|MB_ICONSTOP);
		GenerateUveoml(false,sPackageFile, _T(""), _T(""), _T(""),_T("Некорректен файл реквизитов."));
		return false;
	}
	::SetFileAttributes(sReqFilePath, FILE_ATTRIBUTE_NORMAL);
	::DeleteFile(sReqFilePath);

	AddLog(_T("Файл реквизитов прочитан \n"));


	//Проверка наличия нужных реквизитов

	CString buf, sErrLog;
	CString sId, sName, sVer, sDescr, sType, sLitera, sFormat, sOrg, sEKPS, sShifr;

	sId=mapRequsite.Get(_T("Обозначение"));
	if(sId==_T("")) {if(sErrLog!=_T("")) sErrLog+=_T("\n"); sErrLog+=_T("Отсутствует реквизит \"Обозначение\".");}

	sName=mapRequsite.Get(_T("Наименование"));
	if(sName==_T("")) {if(sErrLog!=_T("")) sErrLog+=_T("\n"); sErrLog+=_T("Отсутствует реквизит \"Наименование\".");}

	sDescr=mapRequsite.Get(_T("Описание"));

	sType=mapRequsite.Get(_T("Вид"));
	if(sType==_T("")) sType=_T("Пакет ЭКД");
	
	sVer=mapRequsite.Get(_T("Версия"));
	if(sVer==_T("")) {if(sErrLog!=_T("")) sErrLog+=_T("\n"); sErrLog+=_T("Отсутствует реквизит \"Версия\".");}

	sLitera=mapRequsite.Get(_T("Литера"));
	sFormat=mapRequsite.Get(_T("Формат"));

	
	sOrg=mapRequsite.Get(_T("Наименование предприятия-разработчика"));
	if(sOrg==_T(""))
	{
		sOrg=mapRequsite.Get(_T("Организация-отправитель"));
		if(sOrg==_T("")) {if(sErrLog!=_T("")) sErrLog+=_T("\n"); sErrLog+=_T("Отсутствует реквизит \"Наименование предприятия-разработчика\".");}
	}
	
	sEKPS=mapRequsite.Get(_T("Группа и класс ЕКПС"));
	if(sEKPS==_T(""))
	{
		sEKPS=FindSubstrInStrMap(mapRequsite,_T("ЕКПС"));
		if(sEKPS==_T(""))
		{
			if(sErrLog!=_T("")) sErrLog+=_T("\n"); 
			sErrLog+=_T("Отсутствует реквизит \"Группа и класс ЕКПС\".");
		}
	}

	sShifr=mapRequsite.Get(_T("Шифр изделия"));

	if(sErrLog!=_T(""))
	{
		buf=_T("Для пакета заданы не все реквизиты! Загрузка невозможна!");
		buf+=_T("\n\n");
		buf+=sErrLog;
		AfxMessageBox(buf,MB_OK|MB_ICONSTOP);
		buf.Replace(_T("\n"),_T("\r\n"));
		AddLog(buf);

		buf=_T("Для пакета заданы не все реквизиты:\n");
		buf+=sErrLog;
		GenerateUveoml(false,sPackageFile, sOrg,sId,sVer,buf);
		return false;
	}

	if(m_bOnlyVerify)
	{
		AfxMessageBox(_T("Пакет проверен и готов к загрузке!"),MB_OK);
		return true;

	}

	CaplInstance *instZavod=0, *instEkpsFolder=0;

	instZavod=FindFolderByName(sOrg,m_api);

	if(0==instZavod)
	{
		buf .Format(APL_T("Предприятие \"%s\" отсутствует в БД. Создать ?"),sOrg);
			if(IDYES!=AfxMessageBox(buf,MB_ICONQUESTION|MB_YESNO)) {AfxMessageBox(_T("Загрузка прекращена!"),MB_OK); return false;}

		instZavod=m_api->m_folder_mgr.CreateFolder(0,sOrg,_T(""));
	}

	/*instEkpsFolder=m_api->m_folder_mgr.FindFolderByName(sEKPS);
	if(0==instEkpsFolder)
	{
		buf .Format(APL_T("Раздел ЕКПС \"%s\" отсутствует в БД. Создать ?"),sEKPS);
		if(IDYES!=AfxMessageBox(buf,MB_ICONQUESTION|MB_YESNO)) {AfxMessageBox(_T("Загрузка прекращена!"),MB_OK); return false;}

		instEKPS=m_api->m_folder_mgr.CreateFolder(0,instEkpsFolder,_T(""));
	}*/
	
	CaplInstance *instEkpsLevel=m_api->m_classifier_mgr.GetClassifierLevelById(sEKPS,m_instEkpsSystem);
	if(0==instEkpsLevel) 
	{
		AfxMessageBox(_T("Указанный в пакете класс ЕКПС отсутствует в БД.\nПакет подготовлен некорректно.\nЗагрузка прекращена!"),MB_OK);
		GenerateUveoml(false,sPackageFile, sOrg,sId,sVer,_T("Указан несуществующий класс ЕКПС."));
		return false;
	}
	m_api->m_classifier_mgr.LoadClassifierInfo(instEkpsLevel);

	// Находим вид документа
	CaplInstance *instDocType=m_api->m_doc_mgr.GetDocumentTypeBN(sType);
	if(0==instDocType) 
	{
		instDocType=m_api->m_data.CreateInstance(m_api->m_doc_mgr.e_dt);
		m_api->m_data.PutAttr(instDocType,m_api->m_doc_mgr.a_dt_pdt,sType);
	}

	CaplInstance *instDoc=m_api->m_doc_mgr.FindDocById(sId);
	CaplInstance *instDocVer=0;
	bool bMakeActive=false;

	if(0==instDoc)
	{
		// Создаем новый документ
		instDoc=m_api->m_doc_mgr.CreateDocument(sId, sName, sDescr,instDocType,sPackagePath);
		if(0==instDoc) {AddLog(_T("Ошибка при создании документа!"),MB_OK); return false;}

		m_api->m_data.GetAttr(instDoc,m_api->m_doc_mgr.a_apl_doc_active,instDocVer);
	}
	else
	{
		m_api->m_doc_mgr.LoadDocInfo(instDoc);
		// Проверяем наличие такой версии
		aplExtent ext_rev;
		m_api->m_doc_mgr.LoadAllDocumentRevision(instDoc,ext_rev);
		int i;
		for(i=0;i<ext_rev.GetSize();i++)
		{
			CaplInstance *InstOldRev=ext_rev[i];
			m_api->m_data.GetAttr(InstOldRev,m_api->m_doc_mgr.a_apl_doc_rev_id,buf);
			if(buf==sVer)
			{
				int cur_crc32=0, old_crc32=0;
				cur_crc32=GetFileCRC32(sPackagePath);
				m_api->m_data.GetAttr(InstOldRev,m_api->m_doc_mgr.a_apl_doc_rev_crc,old_crc32);

				if(cur_crc32==old_crc32){AddLog(_T("Эта версия пакета ЭКД уже загружена в БД!\n\n(Контрольные суммы загружаемой и загруженной версиий совпадают.)"),MB_OK|MB_ICONINFORMATION); return false;}
				else  
				{
					AddLog(_T("В БД уже присутствует версия пакета с таким же обозначением, но другой контрольной суммой!\n\nЗагружаемый пакет подготовлен некорректно.\n\nЗагрузка невозможна!"),MB_OK|MB_ICONSTOP);
					GenerateUveoml(false,sPackageFile, sOrg,sId,sVer,_T("В БД уже присутствует версия пакета с таким же обозначением, но другой контрольной суммой."));
					return false;
				}

				return false;
			}
		}

		// Версии не нашлось - создаем.
		
		instDocVer=m_api->m_doc_mgr.CreateDocumentRevision(instDoc,sPackagePath);
		bMakeActive=true;
	}

	if(0!=instDocVer)
	{
		m_api->m_doc_mgr.SaveRequisiteToRevision(instDocVer,mapRequsite,true);
		//if(sVer!=_T("")) m_api->m_data.PutAttr(instDocVer,m_api->m_doc_mgr.a_apl_doc_rev_id,sVer);
		//if(sLitera!=_T("")) m_api->m_data.PutAttr(instDocVer,m_api->m_doc_mgr.a_apl_doc_rev_litera,sLitera);
		//if(sFormat!=_T("")) m_api->m_data.PutAttr(instDocVer,m_api->m_doc_mgr.a_apl_doc_rev_format,sFormat);
	}

	if(bMakeActive) m_api->m_doc_mgr.CreateChange(instDocVer,true,false);

	m_api->m_folder_mgr.AddToFolder(instZavod,instDoc);
	if(0!=instEkpsFolder) m_api->m_folder_mgr.AddToFolder(instEkpsFolder,instDoc);

	if(0!=instEkpsLevel) m_api->m_classifier_mgr.CreateClassifierAssociation(instDoc,instEkpsLevel);

	if(sShifr!=_T(""))
	{
		CaplInstance *prd=0, *pdf=0;
		prd=m_api->m_prd_mgr.FindPrdById(sShifr);
		if(0!=prd) pdf=m_api->m_prd_mgr.FindPdfById(prd,_T(""));

		if(0!=pdf) m_api->m_prd_mgr.LoadPrdInfo(pdf);
		else if(0!=prd) m_api->m_prd_mgr.LoadPrdInfo(prd);

		if(0==pdf)
		{
			if(0!=prd) pdf=m_api->m_prd_mgr.CreatePdf(prd,_T(""),false);
			else pdf=m_api->m_prd_mgr.CreatePdf(sShifr,_T(""),_T(""),false);

			m_api->m_data.PutAttr(pdf,m_api->m_prd_mgr.a_apl_pdf_type,_T("assembly"));
		}
		
		m_api->m_folder_mgr.AddToFolder(instZavod,pdf);

		m_api->m_doc_mgr.CreateAssociation(pdf,instDoc);
	}

	// Добавляем файлы подписей
	CStringArray saSignFiles;
	bFindSignFilesForPackage(sPackagePath,saSignFiles);
	for(i=0;i<saSignFiles.GetSize();i++)
	{
		CaplInstance *instFile=m_api->m_doc_mgr.CreateFile(saSignFiles[i],true);
		if(0==instFile) continue;
		
		CaplInstance * ass=m_api->m_doc_mgr.CreateAssociation(instDocVer,instFile);
		ass=0;
	}

	//AddLog(_T("Пакет загружен.\r\n"));
	//if(IDYES!=AfxMessageBox(APL_T("Пакет загружен. Подписать ?"),MB_ICONQUESTION|MB_YESNO)) return true;

	AddLog(_T("Подпись загруженного пакета...\n"));

	CaplInstance *instStatus=m_api->m_appr_mgr.FindApprovalStatusBN(_T("Принято на хранение"));
	if(0==instStatus)instStatus=m_api->m_appr_mgr.CreateApprovalStatus(_T("Принято на хранение"));

	LPSTR sCruptSytem=0;
	if(m_use_dig_sign.GetCheck()) sCruptSytem=APL_CRYPTO_PRO_34_10_2012;

	CaplInstance *instSign=m_api->m_appr_mgr.CreateApproval(instDocVer,instStatus,0,0,0,_T("Оператор АСХ"),0,sCruptSytem,0,0,0,0,0,false,false);

	if(0==instSign)  AddLog(_T("Загруженный пакет не подписан!"),MB_ICONSTOP|MB_OK);
	else AddLog(_T("Загруженный пакет подписан!"));

	CString sDbLog,sUserName=_T("Неизвестный");
	CaplInstance *curuser=m_api->m_appr_mgr.GetCurrentPerson();
	if(0!=curuser) m_api->m_appr_mgr.GetPersonName(curuser,sUserName,false);
	
	buf.Format(_T("\nПользователь %s загрузил в БД  пакет \"%s\""),sUserName,sPackagePath);
	 sDbLog+=buf;
	sDbLog+=_T("\nРеквизиты пакета:"); 
	buf.Format(_T("\nОбозначение: %s"),sId);  sDbLog+=buf;
	buf.Format(_T("\nНаименование: %s"),sName); sDbLog+=buf;
	buf.Format(_T("\nВерсия: %s"),sVer); sDbLog+=buf;
	buf.Format(_T("\nПредприятие: %s"),sOrg); sDbLog+=buf;
	buf.Format(_T("\nЕКПС: %s"),sEKPS);sDbLog+=buf;

	AddLog(sDbLog);
	WriteAshMoDBLog(m_api,sDbLog);

	//AfxMessageBox(_T("Пакет загружен!"));
	//if(IDYES!=AfxMessageBox(_T("Пакет загружен! Создать уведомление?"),MB_YESNO|MB_ICONQUESTION)) return true;

	GenerateUveoml(true,sPackageFile, sOrg,sId,sVer,_T(""));
	return true;
}

//***************************************************************************************

//***********************************************************************************

bool CAshMoImportDialog::AshMoVerifyPackage()
{

	CString sCpTestPath=_T("C:\\Program Files\\Crypto Pro\\CSP\\csptest.exe");
	if(!CaplFile::IsFileExist(sCpTestPath))
	{
		sCpTestPath=_T("C:\\Program Files (x86)\\Crypto Pro\\CSP\\csptest.exe");
		if(!CaplFile::IsFileExist(sCpTestPath)){AfxMessageBox(_T("csptest.exe не найден! Работа невозможна!"),MB_ICONSTOP|MB_OK); return false;}
	}

	/*CString sTempPath; sTempPath.GetEnvironmentVariable(_T("TEMP"));
	if(sTempPath[sTempPath.GetLength()]!=_T('\\')) sTempPath+=_T('\\');
	sTempPath+=_T("ASH_MO\\");
	CreateDirectory(sTempPath,NULL);*/

	int i,j;
	CString buf,sPackagePath;
	
	//sPackagePath=_T("C:\\____sign\\3\\111.txt");
	//sPackagePath=_T("C:\\_____ASH\\0\\Package_000000_01.rar");
	CFileDialog f_dlg(TRUE,_T("*.rar"),0,OFN_HIDEREADONLY, APL_T("Файлы архивов (*.rar)|*.rar|Все файлы (*.*)|*.*|"),0);
	if(f_dlg.DoModal()!=IDOK) return false;
	sPackagePath=f_dlg.GetPathName();
		
	/*
	CString sPackageName;
	i=sPackagePath.ReverseFind(_T('\\'));
	j=sPackagePath.ReverseFind(_T('.'));

	if(i>=0 && i<=i) sPackageName=sPackagePath.Mid(i+1,j-(i+1));
	if(sPackageName==_T("")){AfxMessageBox(_T("Некорректное имя пакета! Работа невозможна!"),MB_ICONSTOP|MB_OK); return false;}*/


	// Ищем файлы подписей

	CStringArray saSignFiles;
	bFindSignFilesForPackage(sPackagePath,saSignFiles);
	
	buf.Format(_T("Найдено %i файлов подписей."),saSignFiles.GetCount());
	AfxMessageBox(buf);

	int res;
	CString sCmd, sOutBuf, sSignFile,sTempFile;


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

	for(i=0;i<saSignFiles.GetCount();i++)
	{
		CString sSignFile=saSignFiles[i];
		// Читаем данные о подписях 
		sCmd.Format(_T("\"%s\" -certlic -check -certfile \"%s\""),sCpTestPath,sSignFile);
		res=aplCreateProcessEx(0, sCmd, true, true, &sOutBuf);
		if(0!=res)
		{
			buf.Format(_T("Ошибка при обработке файла подписи '%s'!\nФайл поврежден или имеет неизвестный формат."),sSignFile);
			AfxMessageBox(buf,MB_ICONSTOP|MB_OK);
			continue;
		}

		CStringArray sa;
		CString sLine, sWord,sVal, sSubject, sIssuer, sCertDate;
		str2strArry(sOutBuf,sa);

		for(j=0;j<sa.GetCount();j++)
		{
			sLine=sa[j];
			int k=sLine.Find(_T(':'),0);
			if(k<0) continue;
			sWord=sLine.Left(k);
			sWord.MakeLower(); sWord.TrimRight(); sWord.TrimLeft();
			sVal=sLine.Right(sLine.GetLength()-(k+1)); 
			sVal.TrimLeft(); sWord.TrimRight();
			if(sWord==_T("subject"))  sSubject=sVal;
			else if(sWord==_T("valid"))  sCertDate=sVal;
			else if(sWord==_T("issuer"))  sIssuer=sVal;
		}

		// Проеряем саму подпись

		sCmd.Format(_T("\"%s\" -sfsign -verify -detached -in \"%s\" -signature \"%s\""), sCpTestPath, sPackagePath, sSignFile);
		sOutBuf;
		res=aplCreateProcessEx(0, sCmd, true, true, &sOutBuf);

		if(0==res)
		{
			// Подпись верна
		}
		else if(0x80091007==res)
		{
			buf.Format(_T("Ошибка при проверке подписи в файле\n\n'%s' !\n\nФайл изменен (хеш файла не совпадает с хэшом в подписи)."),sSignFile);
			AfxMessageBox(buf,MB_ICONSTOP|MB_OK); 
			continue;
		}
		else if(0x8009310b==res)
		{
			buf.Format(_T("Ошибка при проверке подписи в файле\n\n'%s' !\n\nВстречено неверное значение тега ASN1."),sSignFile);
			AfxMessageBox(buf,MB_ICONSTOP|MB_OK); 
			continue;
		}
		else if(0!=res)
		{
			buf.Format(_T("Ошибка при проверке подписи в файле '%s' !"),sSignFile);
			AfxMessageBox(buf,MB_ICONSTOP|MB_OK); return false;
			continue;
		}

		sLine=_T("");

	}
	return true;
}

//**********************************************************************************************
bool  CAshMoImportDialog::GenerateUveoml(bool bResult, CString sFileName, CString sRecipient, CString sPackageId, CString sPackageVer, CString sErrors)
{
	//if(IDYES!=AfxMessageBox(_T("Создать уведомление ?"),MB_YESNO|MB_ICONQUESTION)) return false;


	CString buf, sHtml;
	sHtml+=_T("<HTML>\n<HEAD>\n<META HTTP-EQUIV=\"Content-Type\" content=\"text/html; charset=windows-1251\">\n<TITLE>%title%</TITLE>\n</HEAD>\n");
	sHtml+=_T("<BODY>\n<font name = \"Arial\" size = 12>\n");
	sHtml+=_T("<p align=\"right\">%recip%</p><br/>\n");
	sHtml+=_T("<p align=\"center\"><b>%title%<br/>%type%</b></p><br/>\n");
	sHtml+=_T("<p align=\"left\">%text%</p><br/><br/>\n");
	sHtml+=_T("<p align=\"right\">Оператор _____________ %operator%<br/>%date%</p><br/>");
	sHtml+=_T("\n</BODY>\n</HTML>");


	if(bResult)
	{
		if(IDYES!=AfxMessageBox(_T("Пакет успешно загружен! Создать уведомление?"),MB_YESNO|MB_ICONQUESTION)) return true;
	}
	else
	{
		if(IDYES!=AfxMessageBox(_T("При загрузке пакета возникли ошибки!\n\nСоздать уведомление?"),MB_YESNO|MB_ICONSTOP)) return true;
	}
	
	sHtml.Replace(_T("%recip%"),sRecipient);

	int nNumber = m_api->m_options_mgr.GetCounterWithIncrementBN(_T("АСХ МО Номер уведомления"));

	buf.Format(_T("УВЕДОМЛЕНИЕ № %i"),nNumber);
	sHtml.Replace(_T("%title%"),buf);

	buf.Format(_T("uvedomlenie_%i.htm"),nNumber);
	CString sUvedFileName=m_sTempPath+buf;

	if(bResult)
	{
		sHtml.Replace(_T("%type%"),_T("об успешной загрузке пакета ЭКД"));
		buf.Format(_T("Пакет \"%s\" версия \"%s\" успешно загружен в АСХ МО\n из файла \"%s\"."),sPackageId,sPackageVer,sFileName);
		sHtml.Replace(_T("%text%"),buf);
	}
	else
	{
		sHtml.Replace(_T("%type%"),_T("об ошибке при загрузке пакета ЭКД"));

		CString sText=_T("При загрузке пакета ");
		if(sPackageId!=_T(""))
		{
			sText+=_T('\"')+ sPackageId + _T("\" ");
			if(sPackageVer!=_T(""))sText+=_T(" версия\"")+ sPackageVer + _T("\" ");
		}
		if(sFileName!=_T("")) sText+=_T("из файла \"")+ sFileName + _T("\" ");

		if(sErrors==_T("")) sText+=_T("обнаружены ошибки.");
		else
		{
			sText+=_T("обнаружены следующие несоответствия:<br/>");
			sErrors.Replace(_T("\n"),_T("<br/>"));
			sText+=sErrors;
		}
		//sText+=_T("br");
		//sText+=_T("Пакет не загружен\n");

		sHtml.Replace(_T("%text%"),sText);
	}


	buf=_T("Неизвестный");
	CaplInstance *curuser=m_api->m_appr_mgr.GetCurrentPerson();
	if(0!=curuser) m_api->m_appr_mgr.GetPersonName(curuser,buf,true);

	sHtml.Replace(_T("%operator%"),buf);

	COleDateTime odt=COleDateTime::GetCurrentTime(); 
	buf=odt.Format(_T("%d.%m.%Y  %H:%M"));
	sHtml.Replace(_T("%date%"),buf);
	
	//aplShowBigMsg(sHtml);

	if(CaplFile::IsFileExist(sUvedFileName))
	{
		::SetFileAttributes(sUvedFileName, FILE_ATTRIBUTE_NORMAL);
		::DeleteFile(sUvedFileName);
	}

	CStdioFile  fUvedFile;
	if(!fUvedFile.Open(sUvedFileName,CaplFile::modeCreate|CaplFile::modeWrite))
	{
		if(IDYES!=AfxMessageBox(_T("Ошибка создания файла уведомления!"),MB_OK|MB_ICONSTOP)) return false;
	}
	
	fUvedFile.WriteString(sHtml);
	fUvedFile.Flush();
	fUvedFile.Close();

	ShellExecute(0,_T("open"),sUvedFileName,NULL,NULL,SW_SHOW);

	return true;
}



#endif