// CommonETDialog.cpp : implementation file
//

#include "stdafx.h"
#include "CommonETDialog.h"
#include "apl_api.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "dictionary.h"
#include "common.h"
#include "SignDlg.h"
#include "SignQueryDlg.h"
/////////////////////////////////////////////////////////////////////////////
// CCommonETDialog dialog


CCommonETDialog::CCommonETDialog(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CCommonETDialog::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCommonETDialog)
	m_iCon = -1;
	m_sComents = _T("");
	m_sId = _T("");
	m_sName = _T("");
	//}}AFX_DATA_INIT
	
	m_api= NULL;
	m_wf_mgr= NULL;
	m_curApprStatus= NULL;
	m_connector= NULL;
	m_bUseDigSign= true;
	m_bNotSign= true;

	m_defRole= NULL;
	m_defStatus= NULL;

	m_iDenyDubleStatus=0;

	m_bLimitDocTypesByRoles=FALSE;
}


void CCommonETDialog::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCommonETDialog)
	DDX_Control(pDX, IDC_DIG_SIGN_SYS, m_dig_sign_sys_list);
	DDX_Control(pDX, IDC_ROLE_COMBO, m_rolesCombo);
	DDX_Control(pDX, IDOK, m_okBtn);
	DDX_Control(pDX, IDCANCEL, m_cancelBtn);
	DDX_Control(pDX, IDC_SELECT_ALL_BUTTON, m_selAllBtn);
	DDX_Control(pDX, IDC_CLEAR_BUTTON, m_clearBtn);
	DDX_Control(pDX, IDC_APPROVED_WO, m_apprWOList);
	DDX_Control(pDX, IDC_ET_CONNECTOR, m_conCB);
	DDX_CBIndex(pDX, IDC_ET_CONNECTOR, m_iCon);
	DDX_Text(pDX, IDC_ET_CONNECTOR_DSCR, m_sComents);
	DDX_Text(pDX, IDC_ET_TASK_ID, m_sId);
	DDX_Text(pDX, IDC_ET_TASK_NAME, m_sName);
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_ET_WO_NOTES, m_notesBtn);
}


BEGIN_MESSAGE_MAP(CCommonETDialog, CaplResizableDialog)
	//{{AFX_MSG_MAP(CCommonETDialog)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_APPROVED_WO, OnItemchangedApprovedWo)
	ON_BN_CLICKED(IDC_SELECT_ALL_BUTTON, OnSelectAllButton)
	ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClearButton)
	ON_CBN_SELCHANGE(IDC_ET_CONNECTOR, OnSelchangeEtConnector)
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_ET_WO_NOTES, &CCommonETDialog::OnBnClickedEtWoNotes)
	ON_CBN_SELCHANGE(IDC_ROLE_COMBO, &CCommonETDialog::OnCbnSelchangeRoleCombo)
END_MESSAGE_MAP()
 
/////////////////////////////////////////////////////////////////////////////
// CCommonETDialog message handlers

BOOL CCommonETDialog::OnInitDialog() 
{
	CaplResizableDialog::OnInitDialog();
	
	if(m_api && m_api->m_data.IsConnected())
	{
		CaplInstance* activity=NULL;
		if(m_task)m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_activity, activity);
		if(activity)m_api->m_data.GetAttr(activity, m_wf_mgr->a_activity_not_sign, m_bNotSign);
	}

	int i;
	// Инициализация ЭЦП
	{
		m_dig_sign_sys_list.AddString(APL_T("Не использовать ЭЦП"));
		m_dig_sign_sys_list.SetCurSel(0);

		CStringArray array;
		CaplCryptographicManager::GetAllCSP(array,true);

		for(i=0; i<array.GetSize(); i++)
		{
			int n= m_dig_sign_sys_list.AddString(array[i]);
		}

		CString sDefCSPName = CaplCryptographicManager::GetDefaultCSP();
		int iPos= m_dig_sign_sys_list.FindString(-1, sDefCSPName);
		if(CB_ERR!=iPos) m_dig_sign_sys_list.SetCurSel(iPos);
	}

	if(m_bNotSign)
	{
		m_selAllBtn.ShowWindow(SW_HIDE);
		m_clearBtn.ShowWindow(SW_HIDE);
		m_notesBtn.ShowWindow(SW_HIDE);
		m_apprWOList.ShowWindow(SW_HIDE);
		GetDlgItem(IDC_OFRM_STATIC)->ShowWindow(SW_HIDE);

		CRect rect1, rect;

		m_okBtn.GetWindowRect(&rect);
		m_selAllBtn.GetWindowRect(&rect1);
		
		int b= rect.top-rect1.top;

		rect.top-=b;rect.bottom-=b;
		ScreenToClient(&rect);
		m_okBtn.MoveWindow(&rect);
		
		m_cancelBtn.GetWindowRect(&rect);
		rect.top-=b;rect.bottom-=b;
		ScreenToClient(&rect);
		m_cancelBtn.MoveWindow(&rect);

		GetWindowRect(&rect);
		rect.bottom-=b;
		SetMinTrackSize(CSize(rect.right-rect.left, rect.bottom-rect.top));
		SetWindowPos(&wndTop, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, NULL);
	}

	m_cancelBtn.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_cancelBtn.SetFlat(FALSE);
	m_okBtn.SetIcon(GetAplStdIco16(APLSTDICO_OK));
	m_okBtn.SetFlat(FALSE);
	m_notesBtn.SetIcon(aplGetTabCtrlImageList()->ExtractIcon(13));
	m_notesBtn.SetFlat(FALSE);
	m_selAllBtn.SetIcon(GetAplTableIco(APL_TABLE_SELECT_ALL));
	m_selAllBtn.SetFlat(FALSE);
	m_clearBtn.SetIcon(GetAplTableIco(APL_TABLE_UNSELECT_ALL));
	m_clearBtn.SetFlat(FALSE);

	m_apprWOList.SetImageList(aplGetInstImageList(), LVSIL_SMALL);
	m_apprWOList.SetExtendedStyle(m_apprWOList.GetExtendedStyle()|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT|LVS_EX_SUBITEMIMAGES|LVS_EX_CHECKBOXES);
	
	AddAnchor(IDC_TFRM_STATIC,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_PFRM_STATIC,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_ET_CONNECTOR_DSCR,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_OFRM_STATIC,TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_APPROVED_WO,TOP_LEFT, BOTTOM_RIGHT);
	
	AddAnchor(IDC_ET_TASK_ID, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_ET_TASK_NAME, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_ROLE_COMBO, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_ET_CONNECTOR, TOP_LEFT, TOP_RIGHT);
	
	AddAnchor(IDC_SELECT_ALL_BUTTON,TOP_RIGHT);
	AddAnchor(IDC_ET_WO_NOTES,TOP_RIGHT);
	AddAnchor(IDC_CLEAR_BUTTON,TOP_RIGHT);
	AddAnchor(IDC_DIG_SIGN_SYS, BOTTOM_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_STATIC_SIGN, BOTTOM_LEFT);
	AddAnchor(IDC_STATIC_PRIMECH, BOTTOM_LEFT);
	AddAnchor(IDOK,BOTTOM_RIGHT);	
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);	


	// Настройки проверки подписей документов
	m_api->m_options_mgr.GetOptionValueBN( APL_NO_T("Настройка Workflow\\Ограничить проверку документов видами, заданными в роли"), m_bLimitDocTypesByRoles, 0);	
	m_api->m_options_mgr.GetOptionValueBN( APL_NO_T("Статус\\Запретить дублировать подпись другим сотрудником"),m_iDenyDubleStatus,0);


	if(m_api && m_api->m_data.IsConnected())
	{
		CaplInstance* process= NULL;
		CaplInstance* activity= NULL;
		CaplInstance* inst= NULL;
		CaplInstance* role= NULL;
		aplExtent ext, taskProts;
		CString sRoleName;
		int iIndex;
		int i;
		
		if(m_task)
		{
			m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_proc, process);
			m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_activity, activity);
		}
		
		if(process)
		{
			m_wf_mgr->LoadProcessInfo(process);
			m_api->m_data.GetAttr(process, m_wf_mgr->a_proc_wo, m_objects);
			m_api->m_data.GetAttr(process, m_wf_mgr->a_proc_task_prot, taskProts);
			m_api->m_data.GetAttr(process, m_wf_mgr->a_proc_process_prot, inst);

			if(inst)
				m_wf_mgr->GetProcessPrototypeItems(inst, taskProts);
			else
				m_api->m_data.GetAttr(process, m_wf_mgr->a_proc_task_prot, taskProts);
			
			for(int n= 0; n<taskProts.GetSize(); n++)
			{
				m_api->m_data.GetAttr(taskProts[n], m_wf_mgr->a_task_tmpl_activity, inst);
				if(activity && inst==activity)
				{
					m_api->m_data.GetAttr(taskProts[n], m_wf_mgr->a_task_tmpl_role, m_defRole);
					m_api->m_data.GetAttr(taskProts[n], m_wf_mgr->a_task_tmpl_status, m_defStatus);
					break;
				}
			}
		}
		
		if(m_defRole)
			role= m_defRole;
		else if(activity) 
			m_api->m_data.GetAttr(activity, m_wf_mgr->a_activity_role, role);
		
		if(role)
		{
			m_api->m_data.GetAttr(role, m_api->m_appr_mgr.a_po_role_name, sRoleName);
			iIndex= m_rolesCombo.AddString(sRoleName);
			m_rolesCombo.SetItemData(iIndex, (DWORD)role);
			m_rolesCombo.SetCurSel(iIndex);
			m_rolesCombo.EnableWindow(FALSE);
		}
		else
		{
			// обработка ролей из абонента по просьбе ЦКБА
			CaplInstance *official_role=0;
			CaplInstance *performer=0, *official=0;
			m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_performer, performer);
			if(0!=performer){ if(m_api->m_data.IsKindOf(performer,m_api->m_appr_mgr.e_official))official=performer;}
			
			/* Убрано по просьбе ЦКБА 16.05.2019
			if(0==official)
			{
				m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_manager, performer);
				if(0!=performer){ if(m_api->m_data.IsKindOf(performer,m_api->m_appr_mgr.e_official))official=performer;}
			}
			*/
			if(0!=official)
			{
				aplExtent ext;
				m_api->m_data.GetAttr(performer,m_api->m_appr_mgr.a_official_roles, ext);
				if(ext.GetSize()>0)official_role=ext[0];
			}


			// роли текущего сотрудника
			bool bval;
			m_api->m_data.GetAttr(m_api->m_appr_mgr.GetCurrentPerson(), m_api->m_appr_mgr.a_pers_roles, ext);

			if(0!=official_role) ext.Add(official_role);

			for(i= 0; i<ext.GetSize(); i++)
			{
				m_api->m_data.GetAttr(ext[i], m_api->m_appr_mgr.a_po_role_system, bval);
				if(bval) continue;
				m_api->m_data.GetAttr(ext[i], m_api->m_appr_mgr.a_po_role_name, sRoleName);
				iIndex= m_rolesCombo.AddString(sRoleName);
				m_rolesCombo.SetItemData(iIndex, (DWORD)ext[i]);
			}
			
			if(ext.GetSize())
			{
				if(0!=official_role)
				{
					m_api->m_data.GetAttr(official_role, m_api->m_appr_mgr.a_po_role_name, sRoleName);
					m_rolesCombo.SelectString(-1,sRoleName);
				}
				else m_rolesCombo.SetCurSel(0);
			}
		}

		m_apprWOList.InsertColumn(0, APL_T("Объект"), LVCFMT_LEFT, 300);
		m_apprWOList.InsertColumn(1, APL_T("Присваиваемый статус"), LVCFMT_LEFT, 150);
		m_apprWOList.InsertColumn(2, APL_T("Тип объекта"), LVCFMT_LEFT, 120);
	
		CString buf,buf1;
		int n;

		ext.Clear();

		m_api->m_data.GetAttr(m_task, m_wf_mgr->a_action_id, m_sId);
 		m_api->m_data.GetAttr(m_task,  m_wf_mgr->a_action_name, m_sName);

		for(i= 0; i<m_woItems.GetSize(); i++)
		{
			CaplInstance *status, *conn=m_woItems[i];
			m_api->m_data.GetAttr(conn, m_wf_mgr->a_act_rel_name, buf);

			m_api->m_data.GetAttr(conn, m_wf_mgr->a_act_secuence_status, status);
			if(0!=status)
			{
				m_api->m_data.GetAttr(status, m_api->m_appr_mgr.a_appr_status_name, buf1);
				if(buf1!=_T("")){buf+=_T("   /   '"); buf+=buf1; buf+=_T("'");}
			}
			n= m_conCB.AddString(buf);
			m_conCB.SetItemData(n, (DWORD)conn);
		}
	
		if(1==m_conCB.GetCount())
		{
			m_iCon= 0;
			m_connector= (CaplInstance*)m_conCB.GetItemData(0);

			if(m_defStatus) m_curApprStatus= m_defStatus;
			else
			{
				m_api->m_data.GetAttrBN(m_connector, _T("status"), m_curApprStatus);			
				if(!m_bNotSign) // если подписываем по заданию
					m_api->m_data.GetAttr(m_connector, m_wf_mgr->a_act_secuence_not_sign, m_bNotSign);

				if(!m_bNotSign) m_apprWOList.EnableWindow((m_bNotSign)?FALSE:TRUE);
			}
		}
		LoadItemsInfo();
		ShowItems(m_objects);
		int iVal;
		m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Не отмечать объекты при завершении задания"), iVal, 0);
		if(1!=iVal)
		{
			m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Не давать завершать задания без подписи объектов"), iVal, 0);
			if(1==iVal)
			{
				for(i= 0; i<m_apprWOList.GetItemCount(); i++)
					m_apprWOList.SetCheck(i);
			}
		}
	}
	UpdateData(FALSE);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

CString CCommonETDialog::GetTypeName(CaplInstance* inst)
{
	CString sType;
	
	if(!inst) return sType;
	if(!inst->GetType()) return sType;

	if(apidata.IsKindOf(inst, m_api->m_doc_mgr.e_apl_doc))
		sType= APL_T("Документ");
	if(apidata.IsKindOf(inst, m_api->m_doc_mgr.e_apl_doc_rev))
		sType= APL_T("Версия документа");
	else if(apidata.IsKindOf(inst, m_api->m_prd_mgr.e_prd))
		sType= APL_T("Изделие");
	else if(apidata.IsKindOf(inst, m_api->m_prd_mgr.e_apl_pdf))
		sType= APL_T("Версия изделия");
	else if(apidata.IsKindOf(inst, m_api->m_prd_inst_mgr.e_prd_inst))
		sType= APL_T("Экземпляр изделия");
	else if(apidata.IsKindOf(inst, m_api->m_prd_inst_mgr.e_lot))
		sType= APL_T("Партия");
	else if(apidata.IsKindOf(inst, m_api->m_change_mgr.e_chng))
		sType = APL_T("Изменение");
	else if(apidata.IsKindOf(inst, m_api->m_bp_mgr.e_bp))
		sType= APL_T("Бизнес-процесс");
	else if(apidata.IsKindOf(inst, m_api->m_bp_mgr.e_apl_bp_ver))
		sType= APL_T("Бизнес-процесс");
	else if(apidata.IsKindOf(inst, m_api->m_bp_mgr.e_apl_bp_inst))
		sType= APL_T("Экземпляр бизнес-процесса");
	else if(0!=m_api->m_expl_mgr && apidata.IsKindOf(inst, m_api->m_expl_mgr->e_apl_refusal))
		sType= APL_T("Неисправность");
	else if(apidata.IsKindOf(inst, m_api->m_classifier_mgr.e_apl_classifier_system))
		sType= APL_T("Справочник");
	else if(apidata.IsKindOf(inst, m_api->m_classifier_mgr.e_apl_classifier_level))
		sType= APL_T("Элемент справочника");
	else if(apidata.IsKindOf(inst, m_api->m_folder_mgr.e_folder))
		sType= APL_T("Папка");
	else if(apidata.IsKindOf(inst, m_api->m_project_mgr->e_project))
		sType= APL_T("Проект");
	else if(apidata.IsKindOf(inst, m_api->m_appr_mgr.e_person))
		sType= APL_T("Сотрудник");
	else if(apidata.IsKindOf(inst, m_api->m_appr_mgr.e_org))
		sType= APL_T("Организация");
	else if(apidata.IsKindOf(inst, m_api->m_appr_mgr.e_org))
		sType= APL_T("Организация");
	else if(apidata.IsKindOf(inst, m_api->m_message_mgr.e_message))
		sType= APL_T("Сообщение");
	else if(apidata.IsKindOf(inst, m_api->m_doc_mgr.e_doc_copy_order))
		sType= APL_T("Заказ-наряд");
	else sType= inst->GetType()->name;

	return sType;
}

void CCommonETDialog::OnOK() 
{
	UpdateData();
	
	if(-1==m_iCon){MessageBox(APL_T("Переход не указан"), APL_T("Ошибка"), MB_OK|MB_ICONERROR);return;}
	m_connector= (CaplInstance*)m_conCB.GetItemData(m_iCon);
	
	BOOL bItemSel= FALSE;
	aplExtent checkedItems;
	CaplInstance* item= NULL;
	CaplInstance *inst=NULL, /**inst1,*/ *person= NULL, *role=NULL, *act= NULL;
	CaplInstance* doc=NULL;
	int iDocCounte= 0;

	CString str4label;
	bool bSetNeedWork=false, bUnSetNeedWork=false;
	if(0!=m_curApprStatus)
	{
		m_api->m_data.GetAttr(m_curApprStatus,  m_api->m_appr_mgr.a_appr_status_str4label, str4label);	
		m_api->m_data.GetAttr(m_curApprStatus,  m_api->m_appr_mgr.a_appr_status_set_needs_work, bSetNeedWork);
		m_api->m_data.GetAttr(m_curApprStatus,  m_api->m_appr_mgr.a_appr_status_unset_needs_work, bUnSetNeedWork);
		if(bSetNeedWork && bUnSetNeedWork) {bSetNeedWork=false; bUnSetNeedWork=false;}

		bool bNeedDescription = false;
		m_api->m_data.GetAttr(m_curApprStatus, m_api->m_appr_mgr.a_appr_status_need_description, bNeedDescription);
		if(bNeedDescription)
		{
			m_sComents.TrimRight(); m_sComents.TrimLeft();
			
			if(m_sComents==_T(""))
			{
				AfxMessageBox( APL_T("Выбор этогого перехода требует обязательного заполнения поля \"Обоснование\" !!!\n\n(задано в свойствах статуса)"),MB_OK|MB_ICONSTOP);
				return;
			}
		}
	}


	if(m_apprWOList.GetItemCount())
	{
		bItemSel= FALSE;
		for(int i= 0; i<m_apprWOList.GetItemCount(); i++)
		{
			if(m_apprWOList.GetCheck(i))
			{
				bItemSel= TRUE;
				item= (CaplInstance*)m_apprWOList.GetItemData(i);
				if(item)
				{
					if(m_api->m_data.IsKindOf(item, m_api->m_doc_mgr.e_doc))
					{
						m_api->m_data.GetAttr(item, m_api->m_doc_mgr.a_apl_doc_active, inst);
						iDocCounte++;
					}
					else if(apidata.IsKindOf(item, m_api->m_bp_mgr.e_bp))
					{
						m_api->m_data.GetAttr(item, m_api->m_bp_mgr.a_bp_act, inst);
						if(0==inst) inst=item;
					}
					else
					{
						if(m_api->m_data.IsKindOf(item, m_api->m_doc_mgr.e_apl_doc_rev))
							iDocCounte++;
						inst= item;
					}
					checkedItems.Add(inst);
				}
			}
		}
	}
	
	int iVal,iVal1;
	m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Не давать завершать задания без подписи объектов"), iVal, 0);

	if(!m_bNotSign)
	{
		if((!bItemSel && m_apprWOList.GetItemCount()))
			if(0==iVal)
			{
				if(IDNO==AfxMessageBox(APL_T("Вы не указали рабочие объекты для создания ЭП.\n\nПродолжить завершение задачи?"), MB_YESNO|MB_ICONWARNING)) return;
			}
			else
			{
				AfxMessageBox(APL_T("Вы не указали рабочие объекты для создания ЭП!"), MB_OK|MB_ICONERROR); 
				return;
			}
	}

	m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Запрашивать подтверждение выбора перехода"), iVal, 0);
	if(iVal!=0)
	{
		CString sMessage;
		CString sBufName;
		CString sBufTask;
		CaplInstance* ciTo;
		m_api->m_data.GetAttr(m_connector, m_wf_mgr->a_act_rel_name, sBufName);
		m_api->m_data.GetAttr(m_connector, m_wf_mgr->a_act_rel_to, ciTo);
		if(ciTo)
		{
			sMessage= APL_T("Вы действительно хотите выбрать переход \"")+sBufName+_T("\" и \n");
			if(m_api->m_data.IsKindOf(ciTo, m_wf_mgr->e_activity))
			{
				m_api->m_data.GetAttr(ciTo, m_wf_mgr->a_action_name, sBufTask);
				sMessage+=APL_T("перейти к заданию \"")+sBufTask+_T("\"?");
			}
			else if(m_api->m_data.IsKindOf(ciTo, m_wf_mgr->e_end_point))
			{
				sMessage+=APL_T("завершить процесс?");
			}
			if(IDNO==AfxMessageBox(sMessage, MB_OK|MB_YESNO))
				return;
		}
	}
	
	if(FALSE==m_wf_mgr->RunProgrammModule(m_task, checkedItems, m_connector, false))
	{
		AfxMessageBox(APL_T("Не удалось выполнить дополнение завершения задания."), MB_ICONERROR|MB_OK);
		return; 
	}

	int i;
	CString buf;
	//проверяем заполненность реквизитов у документов
	for(i= 0; i<m_apprWOList.GetItemCount(); i++)
	{
		if(!m_apprWOList.GetCheck(i)) continue;
		inst= (CaplInstance*)m_apprWOList.GetItemData(i);
		if(!inst) continue;
		CaplInstance *inst1;
		if(m_api->m_data.IsKindOf(inst, m_api->m_doc_mgr.e_doc))
		{
			m_api->m_data.GetAttr(inst, m_api->m_doc_mgr.a_apl_doc_active, inst1);
		}
		else inst1= inst;

		/*Проверка наличия всех обязательных реквизитов*/
		if(m_api->m_data.IsKindOf(inst1, m_api->m_doc_mgr.e_apl_doc_rev))
		{
			if(!m_api->m_doc_mgr.HasAllNecessaryEntries(inst1))
			{
				//if(m_api->m_ModeInteractive) // это в диалоге и проверка не нужна
				{	
					m_api->m_data.GetAttr(inst1, m_api->m_doc_mgr.a_apl_doc_rev_doc, doc);
					CString id;
					m_api->m_data.GetAttr(doc, m_api->m_doc_mgr.a_doc_id, id);
					
					buf.Format(APL_T("У документа \"%s\" заданы не все постоянные реквизиты! \n\nПодписание невозможно!"), id);
					AfxMessageBox(buf, MB_OK|MB_ICONSTOP);
				}
				return;
			}
		}
	}

	CString cryptSystem;

	if (m_dig_sign_sys_list.GetCurSel()!=0)
	{
		m_dig_sign_sys_list.GetWindowText(cryptSystem);
	}

	bool bAlwaysDigitalSign=false;

	if(checkedItems.GetSize()>0)
	{
		m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка документов\\Всегда подписывать документы ЭЦП"), iVal, 0);
		m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка документов\\Всегда подписывать изменения ЭЦП"), iVal1, 0);
		if(0!=iVal || 0!=iVal1 )
		{
			bAlwaysDigitalSign=true;
			if (cryptSystem==_T(""))
			{
				AfxMessageBox(APL_T("Не выбрана система ЭЦП"), MB_ICONERROR|MB_OK);
				return; 
			}
		}
	}
	

	
	CString sRole;
	//роль как было...
	CaplAggr aggr, aggr0;

	
	//статус
	if(m_defStatus)
		m_curApprStatus= m_defStatus;
	else
		m_api->m_data.GetAttrBN(m_connector, _T("status"), m_curApprStatus);

	role=(CaplInstance*)m_rolesCombo.GetItemData(m_rolesCombo.GetCurSel());
	if(!role)
	{
		AfxMessageBox(APL_T("Не задана роль."), MB_OK|MB_ICONERROR);
		return;
	}	
	m_api->m_data.GetAttr(role, m_api->m_appr_mgr.a_po_role_name, sRole);
	
	//person_and_organization
	CaplInstance* per_org= NULL;
	 aplExtent ext;

	 CaplInstance* curUser= m_api->m_data.GetCurrUser();
	 m_api->m_data.GetAttr(curUser, m_api->m_appr_mgr.a_apl_user_po, per_org);
	
	//дата
	COleDateTime odt= COleDateTime::GetCurrentTime();
	m_api->m_data.NET_GetServerDateTime(odt);
	aplDate2String(odt, buf);	
	
	int n= m_apprWOList.GetItemCount();
	CaplInstance* inst1= NULL;
	
//	bool bDigSign= true; //подписывать ли документы вообще
	bool bDigSignThis= false; //подписывать ли текущий рабочий объект
	bool bFreesAppr= false; // ставить доступ на статусы
	BOOL bAllSign= FALSE; //выбрано "для всех" с диалоге
	
	aplExtent allAppr;
	aplExtent allApprItems;
	
	aplUsers usersList;
	aplAccessList *accessList = new aplAccessList;
	accessList->user= NULL;

	usersList.Add(accessList);

	bool bModeInter= m_api->m_ModeInteractive;
	m_api->SetModeInteractive(false);


	/*Для ЧКистов*/

	//if(m_Crypto.GetCurUsedCSP().IsEmpty())
	{
		m_bUseDigSign= false;
		bAllSign= TRUE;
	}

	m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Устанавливать доступ статусам \"Только чтение\""), iVal, 0);
	if(0!=iVal)
		bFreesAppr= true; // статусы замораживаются

	CaplAttrValue find_value[5];
	find_value[0].attr= m_api->m_appr_mgr.a_appr_item;
	find_value[1].attr= m_api->m_appr_mgr.a_appr_role;
	find_value[2].attr= m_api->m_appr_mgr.a_appr_status;
	find_value[3].attr= m_api->m_appr_mgr.a_appr_pers_org;
	find_value[4].attr= m_api->m_appr_mgr.a_appr_revocation_date_time;


	aplExtent ext_doc_rev_4_setaccess;

	bool bHAsError=false;
	CaplAdminModeProvider adminmode(&(m_api->m_data),-1, -1,DEF_SOURCE);

	// подписываем
	// Устанавливаем режим подписи без повторного запроса пароля и контейнера
	ESignMode OldMode = m_api->m_appr_mgr.SeSignModeForCryptMgr(APL_QUICK_MODE_WITHOUT_DLG);
	
	//long wd= aplStartWaitDlg(APL_T("Идет подпись рабочих объектов. Ждите..."));

	for(i= 0; i<n; i++)
	{
		if(!m_apprWOList.GetCheck(i)) continue;
		
		inst= NULL;
		inst= (CaplInstance*)m_apprWOList.GetItemData(i);
		if(!inst) continue;
		
		inst1= NULL;
		if(m_api->m_data.IsKindOf(inst, m_api->m_doc_mgr.e_doc))
		{
			m_api->m_data.GetAttr(inst, m_api->m_doc_mgr.a_apl_doc_active, inst1);
			doc= inst;
		}
		else if(apidata.IsKindOf(inst, m_api->m_bp_mgr.e_bp))
		{
			m_api->m_data.GetAttr(inst, m_api->m_bp_mgr.a_bp_act, inst1);
			//if(0==inst1) inst1=inst;
			if(0==inst1) 
			{
				// Подпись надо ставить на версию БП. Если версии нет - создаем.
				CString num=_T("");
				inst1=m_api->m_bp_mgr.GetLatestBPVersion(inst,num);
				if(inst1)
					m_api->m_data.PutAttr(inst, m_api->m_bp_mgr.a_bp_act, inst1);
				else
				{
					aplExtent ext_char,ext_group;
					m_api->m_charact_mgr.FindAssociatedCharacteristic(inst, ext_char, ext_group, true);
					inst1=m_api->m_bp_mgr.CreateBPVersion(inst,_T("0"));
				}
			}
			else
			{
				// ЯАИ: 15.10.2025  Исправление косяка загрузки
				#ifdef _UNICODE
				if(inst->GetAccessmode()<=aplRW)
				{
					CaplInstance *bp0=0;
					m_api->m_data.GetAttr(inst1, m_api->m_bp_mgr.a_bp_ver_bp, bp0);
					if(0==bp0)
					{
						m_api->m_data.PutAttr(inst1, m_api->m_bp_mgr.a_bp_ver_bp, inst);
						m_api->SaveChanges();
					}
				}
				#endif
			}
		}
		else
		{
			doc= NULL;
			inst1= inst;
		}

		bDigSignThis=false;
		if(m_api->m_data.IsKindOf(inst1, m_api->m_doc_mgr.e_apl_doc_rev) ||
			m_api->m_data.IsKindOf(inst1, m_api->m_change_mgr.e_chng)) 
			
			bDigSignThis=true;
			
		CaplInstance* appr= NULL;
		aplAccessEl *accessEL= NULL;
		
		find_value[0].value.Set(inst1);
		find_value[1].value.Set(sRole);
		find_value[2].value.Set(m_curApprStatus);
		find_value[3].value.Set(per_org);
		find_value[4].value.Set(_T(""));

		m_api->m_data.NET_FindInstancesWithAttrValues(m_api->m_appr_mgr.e_apl_appr_pers_org, 5, &find_value[0], ext, false);
		if(ext.GetSize())
			appr= ext[0];		

		if(!appr)
		{
			CString sHash, sOpenKey, sSignature, sUser, sCert,sInventory,sSnapShot;
			if(bDigSignThis && cryptSystem!=_T(""))
			{
					if(!m_api->m_appr_mgr.SignObject(inst1, cryptSystem, 
						sSignature, sHash, sOpenKey,sUser,sCert,sInventory,sSnapShot))
					{
						AfxMessageBox(APL_T("Ошибка при присвоении ЭЦП!!!"),MB_OK|MB_ICONSTOP);				
						bHAsError=true;

						if(bAlwaysDigitalSign) return;
						break;			
					}
			}

			appr= m_api->m_data.CreateInstance(m_api->m_appr_mgr.e_apl_appr_pers_org);
			if(appr)
			{
				if (bDigSignThis)
					ext_doc_rev_4_setaccess.Add(inst1);
				// записываем значения реквизитов , участвующих в подписи
				m_api->m_appr_mgr.CreateEntryApproval(inst1, appr);

				m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_item, inst1);
				m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_appr_date_time_s, buf);	
				m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_status, m_curApprStatus);
				m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_notes, m_sComents);
				
				m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_pers_org, per_org);
				m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_role, sRole);

				CString sStatusState;
				if(m_curApprStatus)
					m_api->m_data.GetAttr(m_curApprStatus, m_api->m_appr_mgr.a_appr_status_set_state, sStatusState);
				
				if(!sStatusState.IsEmpty())
				{
					bool bModeInteractive= m_api->m_ModeInteractive;
					m_api->SetModeInteractive(false);
					m_api->m_appr_mgr.ChangeWFState(((doc!=NULL)?doc:inst1), sStatusState, APL_NOT_TEST_POSSIBLE_STATES);
					m_api->SetModeInteractive(bModeInteractive);
				}
				
				if(bDigSignThis && cryptSystem!=_T(""))
				{
					m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_dg_sign_met, cryptSystem);
					m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_dg_sign, sSignature);
					m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_dg_sign_open_key, sOpenKey);
					m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_dg_sign_hash, sHash);
					m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_dg_sign_author, sUser);
					m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_dg_sign_inventory, sInventory);
					m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_dg_sign_snapshot, sSnapShot);

					m_api->m_data.PutAttr(appr, m_api->m_appr_mgr.a_appr_entries_used, true);					

					if(sCert!=_T(""))
					{
						long blob;
						if(!m_api->m_data.NET_SaveBlob(appr,m_api->m_appr_mgr.a_appr_dg_sign_cert,sCert,blob))
							AfxMessageBox(APL_T("Сертификат не найден!"),MB_OK|MB_ICONSTOP);
					}
				}

				allAppr.Add(appr);
				allApprItems.Add(inst);

				if(str4label!=_T("")) m_api->m_appr_mgr.AddLabel4DocRevision(inst1,str4label);
				if(bSetNeedWork)  m_api->m_appr_mgr.SetNeedWork4DocRevision(inst1, true, true);
				else if(bUnSetNeedWork)  m_api->m_appr_mgr.SetNeedWork4DocRevision(inst1, false, true);
			}

			if(bFreesAppr)
			{
				accessEL = new aplAccessEl;
				accessEL->access= aplRO;
				accessEL->inst= appr;
				accessList->Add(accessEL);		
			}
		}
	}//for(;GetItemCount;)
	m_api->m_appr_mgr.PostUpdateApprovalItems(allApprItems);
	m_api->m_appr_mgr.SeSignModeForCryptMgr(OldMode);
	m_api->SetModeInteractive(bModeInter);
	
	m_api->m_data.NET_SaveChanges();
	if(bFreesAppr)
		m_api->m_data.NET_SetGroupeAccess(usersList, APL_T("Установка доступа"));

	if(ext_doc_rev_4_setaccess.GetSize()>0)
	{
		// ААА. Для квз это не нужно
		//if (0 != sDistrCode.CompareNoCase(_T("KVZ")))
		if (!m_api->m_options_mgr.CheckInstallCode(_T("KVZ")))
			apidata.NET_SetInstancesAccess(&ext_doc_rev_4_setaccess,(CaplInstance *)-1,aplRO);
	}

	adminmode.ExitAdminMode();


	// Проверяем - а не перезапустили ли задание за это время
	m_wf_mgr->LoadTaskInfo(m_task);
	CString sStateAfterUpdate;
	m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_state, sStateAfterUpdate);

	if(!(sStateAfterUpdate==_T("work") || sStateAfterUpdate==_T("active") || sStateAfterUpdate==_T("notify")))
	{
		AfxMessageBox(_T("Состояние задания было изменено другим пользователем!\n\nЗавершение задания невозможно!"),MB_OK|MB_ICONSTOP);

		return CaplResizableDialog::OnCancel();
	}

	



	//aplEndWaitDlg(wd);
	if(bHAsError) return;

	CaplResizableDialog::OnOK();
}

void CCommonETDialog::OnCancel() 
{		
	CaplResizableDialog::OnCancel();
}

void CCommonETDialog::LoadItemsInfo()
{
	CaplInstance* inst= NULL;
	CaplInstance* inst1= NULL;
	m_doc_rev_from_objects.Clear();
	
	aplExtent ext, ext4Approval;

	int i,j;
	for(j= 0; j<m_objects.GetSize(); j++)
	{
		if(!m_objects[j]) continue;
		if(m_objects[j]->GetAccessmode()>aplRO) continue;
		
		m_api->m_data.GetAttr(m_objects[j], m_wf_mgr->a_wo_object, inst);
		
		if(!inst) continue;
		if(!inst->GetType()) continue;
		if(!inst->GetId()) continue;
		if(inst->GetAccessmode()>aplRO) continue;

		ext.Add(inst);
	}
	m_api->LoadExtentInfo(ext);

	for(i=0;i<ext.GetSize();i++)
	{
		inst=ext[i];
		
		if(m_api->m_data.IsKindOf(inst, m_api->m_doc_mgr.e_apl_doc))
		{
			m_api->m_data.GetAttr(inst, m_api->m_doc_mgr.a_apl_doc_active, inst1);
		}
		else if(apidata.IsKindOf(inst, m_api->m_bp_mgr.e_bp))
		{
			m_api->m_data.GetAttr(inst, m_api->m_bp_mgr.a_bp_act, inst1);
			if(0==inst1) inst1=inst;
		}
		else inst1= inst;

		if(inst1) ext4Approval.Add(inst1);

		if(m_api->m_data.IsKindOf(inst1, m_api->m_doc_mgr.e_apl_doc_rev))
			m_doc_rev_from_objects.Add(inst1);
	}
	m_api->m_appr_mgr.LoadItemApproval(ext4Approval, m_allAppr, true);
}


bool CCommonETDialog::FindApproval(CaplInstance *inst1, CaplInstance *cur_person, LPCTSTR sRole)
{
	CaplInstance *item, *status, *po;
	CString buf;
	for(int j= 0; j<m_allAppr.GetSize(); j++)
	{
		m_api->m_data.GetAttr(m_allAppr[j], m_api->m_appr_mgr.a_appr_item, item);
		if(item!=inst1) continue;

		m_api->m_data.GetAttr(m_allAppr[j], m_api->m_appr_mgr.a_appr_role, buf);
		if(buf.CompareNoCase(sRole)) continue;

		m_api->m_data.GetAttr(m_allAppr[j], m_api->m_appr_mgr.a_appr_status, status);
		if(status!=m_curApprStatus) continue;

		if(0==m_iDenyDubleStatus) // Важно кто подписал
		{
			m_api->m_data.GetAttr(m_allAppr[j], m_api->m_appr_mgr.a_appr_pers_org, po);
			if(po!=cur_person) continue;
		}

		m_api->m_data.GetAttr(m_allAppr[j], m_api->m_appr_mgr.a_appr_revocation_date_time, buf);
		if(!buf.IsEmpty()) continue; // аннннулировано

		return true;
	}
	return false;
}

void CCommonETDialog::ShowItems(aplExtent &items)
{
	CaplMap checkMap;
	int n= m_apprWOList.GetItemCount();
	int i;
	for(i= 0; i<n; i++)
	{
		checkMap.Add((long)m_apprWOList.GetItemData(i), (long)m_apprWOList.GetCheck(i));
	}
	checkMap.SortIn();
	m_apprWOList.DeleteAllItems();

	if(m_bNotSign) // то показывать объекты не надо, скрываем лишнее и size'им
	{
		return;
	}
	
	bool bForNote;
	CaplInstance* inst= NULL;
	CaplInstance* inst1= NULL;
	CaplInstance* activity;
	CaplInstance* role;
	CString sRole;
	CString type, buf, name;
	int ico, nIndex, iVal;
	bool bHasAppr;
	bool bShowApproved= true;

	CaplInstance* cur_person=m_api->m_appr_mgr.GetCurrentPerson();
	
	m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_activity, activity);
	if(activity) m_api->m_data.GetAttr(activity, m_wf_mgr->a_activity_role, role);
	if(m_defRole) role= m_defRole;
	if(role)m_api->m_data.GetAttr(role, m_api->m_appr_mgr.a_po_role_name, sRole);
	else
	{
		// нет роли - нет подписи - нет завершения заданию
		nIndex = m_rolesCombo.GetCurSel();
		if(nIndex == -1)
		{ 
			AfxMessageBox(APL_T("Невозможно завершить задание, так как у пользователя нет ни одной роли. Обратитесь к администратору."), MB_ICONSTOP); 
			OnCancel();
			return; 
		}

		role=(CaplInstance*)m_rolesCombo.GetItemData(nIndex);
		if(role)
			m_api->m_data.GetAttr(role, m_api->m_appr_mgr.a_po_role_name, sRole);		
	}
	
	/*не выводим для подписи утвержденные объекты*/
	if(m_curApprStatus)
	{
		m_api->m_data.GetAttr(m_curApprStatus, m_api->m_appr_mgr.a_appr_status_set_state, buf);
		if(buf!=_T("")) 
		{
			m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Не подписывать утвержденные объекты статусами, меняющими состояние"), iVal, 0);
			if(0!=iVal)
				bShowApproved= false;
		}
	}

	for(i= 0; i<items.GetSize(); i++)
	{
		if(!items[i]) continue;
		if(items[i]->GetAccessmode()>aplRO) continue;
		
		m_api->m_data.GetAttr(items[i], m_wf_mgr->a_wo_for_note, bForNote);
		if(bForNote) continue;
		m_api->m_data.GetAttr(items[i], m_wf_mgr->a_wo_object, inst);
		
		if(!inst) continue;
		if(!inst->GetType()) continue;
		if(!inst->GetId()) continue;
		if(inst->GetAccessmode()>aplRO) continue;

		bHasAppr= false;
		
		if(m_api->m_data.IsKindOf(inst, m_api->m_doc_mgr.e_apl_doc))
		{
			m_api->m_data.GetAttr(inst, m_api->m_doc_mgr.a_apl_doc_active, inst1);
		}
		else if(apidata.IsKindOf(inst, m_api->m_bp_mgr.e_bp))
		{
			m_api->m_data.GetAttr(inst, m_api->m_bp_mgr.a_bp_act, inst1);
			if(0==inst1) inst1=inst;
		}
		else 
			inst1= inst;


		bHasAppr=FindApproval(inst1, cur_person, sRole);
		
		if(bHasAppr) continue;

		if(!bShowApproved)
		{
			if(m_api->m_data.IsKindOf(inst, m_api->m_doc_mgr.e_doc))
			{
				m_api->m_data.GetAttr(inst, m_api->m_doc_mgr.a_apl_doc_wf_state, buf);
			}
			else if(m_api->m_data.IsKindOf(inst, m_api->m_prd_mgr.e_pdf)) 
			{
				m_api->m_data.GetAttr(inst, m_api->m_prd_mgr.a_apl_pdf_state, buf);
			}
			else if(m_api->m_data.IsKindOf(inst, m_api->m_bp_mgr.e_bp)) 
			{
				m_api->m_data.GetAttr(inst, m_api->m_bp_mgr.a_bp_state, buf);
			}
			else if(m_api->m_data.IsKindOf(inst, m_api->m_change_mgr.e_chng))
			{
				m_api->m_data.GetAttr(inst, m_api->m_change_mgr.a_chng_state, buf);
			}

			if(buf==_T("approved") || buf==_T("applied") || buf==_T("canceled"))
				continue;
		}
		m_api->GetItemName(inst, name);
		ico= m_api->GetInstIco(inst);
		type= GetTypeName(inst);

		if(!name.IsEmpty())
		{
			int n= m_apprWOList.GetItemCount();
			int m= m_apprWOList.InsertItem(n, name, ico);
			m_apprWOList.SetItemData(m, (DWORD)inst);
			m_apprWOList.SetItemText(m, 2, type);

			if(checkMap.QGetByIn((long)inst)>0)
				m_apprWOList.SetCheck(m);
		}
	}
	
	UpdateData(FALSE);
}

void CCommonETDialog::OnItemchangedApprovedWo(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

	BOOL bCheck= FALSE;
	bool bChange= false;
	CString buf;

	if(pNMListView->uNewState==0x2000) //добавили
	{
		bCheck= TRUE; bChange= true;
		if(m_curApprStatus)
		{
			m_api->m_data.GetAttr(m_curApprStatus, m_api->m_appr_mgr.a_appr_status_name, buf);
		}
	}
	else if(pNMListView->uNewState==0x1000) //удалили
	{
		bChange= true;
		buf= _T("");
	}

	if(bChange)
	{
		m_apprWOList.SetItemText(pNMListView->iItem, 1, buf);
		bool bSel= false;
		
		POSITION pos = m_apprWOList.GetFirstSelectedItemPosition();
		if (pos)
		{
			
			while (pos)
			{
				int nItem = m_apprWOList.GetNextSelectedItem(pos);
				if(!bSel)
				{
					if(nItem==pNMListView->iItem)
					{
						bSel= true;
						pos= m_apprWOList.GetFirstSelectedItemPosition();
					}
				}
				else
				{
					m_apprWOList.SetCheck(nItem, bCheck);
					m_apprWOList.SetItemText(nItem, 1, buf);
				}
			}
		}
	}
	
	*pResult = 0;
}



void CCommonETDialog::OnSelectAllButton() 
{
	int n= m_apprWOList.GetItemCount();
	for(int i= 0; i<n; i++)
		if(!m_apprWOList.GetCheck(i)) m_apprWOList.SetCheck(i, TRUE);
	
	OnSelchangeEtConnector();
}

void CCommonETDialog::OnClearButton() 
{
	int n= m_apprWOList.GetItemCount();
	for(int i= 0; i<n; i++)
	{
		if(m_apprWOList.GetCheck(i)) m_apprWOList.SetCheck(i, FALSE);
		m_apprWOList.SetItemText(i, 1, _T(""));
	}
}

void CCommonETDialog::OnSelchangeEtConnector() 
{
	UpdateData();
	
	if(-1==m_iCon) return;

	m_connector= (CaplInstance*)m_conCB.GetItemData(m_iCon);
	CString sStatusNаmе;
	if(0==m_connector) {UpdateData(FALSE); ShowItems(m_objects); return;}
	
	if(m_defStatus) m_curApprStatus= m_defStatus;
	else
	{
		m_api->m_data.GetAttr(m_connector, m_wf_mgr->a_act_secuence_status, m_curApprStatus);
		
		CaplInstance* activity=NULL;
		if(m_task)m_api->m_data.GetAttr(m_task, m_wf_mgr->a_task_activity, activity);
		if(activity)m_api->m_data.GetAttr(activity, m_wf_mgr->a_activity_not_sign, m_bNotSign);
		
		if(!m_bNotSign) // если не подписываем по заданию
			m_api->m_data.GetAttr(m_connector, m_wf_mgr->a_act_secuence_not_sign, m_bNotSign);
		
		if(!m_bNotSign) m_apprWOList.EnableWindow((m_bNotSign)?FALSE:TRUE);
	}

	if(m_curApprStatus)	m_api->m_data.GetAttr(m_curApprStatus, m_api->m_appr_mgr.a_appr_status_name, sStatusNаmе);

	int i;
	bool b;

	// Проверка флага требует доработки
	m_api->m_data.GetAttr(m_connector, m_wf_mgr->a_act_secuence_check_need_work_4_all_obj, b);
	if(b)
	{
		for(i=0;i<m_objects.GetSize();i++)
		{
			CaplInstance *rev=0, *inst=m_objects[i];
			if(0==inst) continue;
			if(inst->IsDeleted()) continue;
			m_api->m_data.GetAttr(inst, m_wf_mgr->a_wo_object, inst);
			if(0==inst) continue;
			if(inst->IsDeleted()|| (inst->GetAccessmode()>aplRO) )continue;

			if(m_api->m_data.IsKindOf(inst,m_api->m_doc_mgr.e_apl_doc_rev)) rev=inst;
			else if(m_api->m_data.IsKindOf(inst,m_api->m_doc_mgr.e_doc))
			{
				m_api->m_data.GetAttr(inst, m_api->m_doc_mgr.a_apl_doc_active, rev);
			}
			if(0==rev) continue;
			if(rev->IsDeleted()|| (rev->GetAccessmode()>aplRO) )continue;
			bool bNeedWork;
			m_api->m_data.GetAttr(rev, m_api->m_doc_mgr.a_apl_doc_rev_it_needs_work, bNeedWork);
			if(bNeedWork)
			{
				m_connector=0; m_curApprStatus=0;
				UpdateData(FALSE);
				ShowItems(m_objects);
				m_conCB.SetCurSel(-1);
				AfxMessageBox(APL_T("Некоторые объекты отмечены как 'требуют доработки' !\n\nПереход невозможен!"),MB_ICONSTOP|MB_OK);
				return;
			}
		}
	}

	UpdateData(FALSE);
	ShowItems(m_objects);

	CaplInstance* cur_person=m_api->m_appr_mgr.GetCurrentPerson();

	// Проверка флага проверять статусы
	m_api->m_data.GetAttr(m_connector, m_wf_mgr->a_act_secuence_check_status_4_all_obj, b);
	if(b)
	{
		if(m_bLimitDocTypesByRoles) // проверяем документы ограниченных видов
		{
			// нет роли - нет подписи - нет завершения заданию
			CString sRole;
			CaplInstance *role=0;
			int nIndex = m_rolesCombo.GetCurSel();
			if(nIndex >=0) role=(CaplInstance*)m_rolesCombo.GetItemData(nIndex);

			if(0==role)
			{
				m_connector=0; m_curApprStatus=0;
				UpdateData(FALSE);
				ShowItems(m_objects);
				m_conCB.SetCurSel(-1);
				AfxMessageBox(APL_T("Не задана или не выбрана роль!"),MB_ICONSTOP|MB_OK);
				return;
			}

			m_api->m_data.GetAttr(role, m_api->m_appr_mgr.a_po_role_name, sRole);

			bool bSpecDocTypeSet;
			aplExtent doc_types;
			m_api->m_data.GetAttr(role,  m_api->m_appr_mgr.a_po_role_specified_document_types_set,bSpecDocTypeSet);
			if(bSpecDocTypeSet)
			{
				m_api->m_data.GetAttr(role, m_api->m_appr_mgr.a_po_role_document_types,doc_types);
				CSortClass::SortExtentByInst(doc_types);
			}

			int i;
			CString buf,sNoApprovalDocList;
			for(i= 0; i<m_doc_rev_from_objects.GetSize(); i++)
			{
				CaplInstance *doc_rev=m_doc_rev_from_objects[i];

				//проверяем по видам документов
				if(bSpecDocTypeSet)
				{
					// фильтр по видам документов
					CaplInstance *doc,*dt=0;
					m_api->m_data.GetAttr(doc_rev, m_api->m_doc_mgr.a_apl_doc_rev_doc, doc);
					if(doc) m_api->m_data.GetAttr(doc, m_api->m_doc_mgr.a_doc_kind, dt);
					if(0!=dt)
					{
						if(-1==aplQFindInstInExtent(doc_types,dt)) continue;
					}
				}

				//проверяем подписи
				if(!FindApproval(doc_rev, cur_person, sRole))
				{
					m_api->GetItemName(doc_rev,buf);
					if(sNoApprovalDocList!=_T("")) sNoApprovalDocList+=_T("\n");
					sNoApprovalDocList+=buf;
				}
			}
			if(sNoApprovalDocList!=_T(""))
			{
				m_connector=0; m_curApprStatus=0;
				UpdateData(FALSE);
				ShowItems(m_objects);
				m_conCB.SetCurSel(-1);

				buf=APL_T("Переход невозможен!\n\nНе все объекты подписаны требуемым статусом и ролью!");
				buf+=APL_T("\n\nНе подписанные объекты:\n\n");
				buf+=sNoApprovalDocList;

				AfxMessageBox(buf,MB_ICONSTOP|MB_OK);
				return;
			}
		}
		else 
		{
			// Проверяем по старинке
			if (m_apprWOList.GetItemCount()>0)
			{
				m_connector=0; m_curApprStatus=0;
				UpdateData(FALSE);
				ShowItems(m_objects);
				m_conCB.SetCurSel(-1);
				AfxMessageBox(APL_T("Переход невозможен!\n\nНе все объекты подписаны требуемым статусом и ролью!"),MB_ICONSTOP|MB_OK);
				return;
			}
		}
	}
}

bool CCommonETDialog::SignWO(CaplInstance* doc, CString sSystem, CString &sKey, CString &sPassword, 
		CString &sSign, CString &sHash, CString &sOpenKey)
{
	if(!doc) return false;
	if(!m_api->m_data.IsKindOf(doc, m_api->m_doc_mgr.e_apl_doc_rev)) return false;

	CString sPath, sFileName;
	long lLen= 0;
	char* bBuf= NULL;

	aplGetTempPath(sPath);

	if(m_api->m_doc_mgr.LoadRevision(doc, sPath))
	{
		CFile file;
		CFileStatus filest;
		CString sFileName;
		if(m_api->m_doc_mgr.GetFileName(doc, sFileName))
			sPath+=sFileName;
		if(!file.Open(sPath, 
			CFile::modeRead|CFile::typeBinary|CFile::shareDenyNone)) return false;
		file.GetStatus(filest);
		if(filest.m_size>0)
		{
			bBuf=new char[(int)(filest.m_size)+4];
#if _MSC_VER >= 1400
			file.Read(bBuf, (UINT)(filest.m_size));
#else
			file.ReadHuge(bBuf, filest.m_size);
#endif
			lLen= (long)(filest.m_size);
		}
		file.Close();
		if(::SetFileAttributes(sPath, FILE_ATTRIBUTE_NORMAL))
			CFile::Remove(sPath);
	}
	if(!bBuf) return false;
	if(!lLen) return false;


	LPCTSTR szPrvKeyFile= sKey.GetBuffer(512),
		szPassword= sPassword.GetBuffer(512);

	CString user,cert;

	sPassword.ReleaseBuffer();
	sKey.ReleaseBuffer();
	if(bBuf){delete [] bBuf;bBuf= NULL;}
	
	if(sHash.IsEmpty() || sOpenKey.IsEmpty() || sSign.IsEmpty()) return false;

	return true;
}

void CCommonETDialog::OnBnClickedEtWoNotes()
{
	int nItem;
	CaplInstance* inst= NULL;
	POSITION pos = m_apprWOList.GetFirstSelectedItemPosition();
	if (pos)
	{
		while (pos)
		{
			nItem = m_apprWOList.GetNextSelectedItem(pos);
			{
				inst= (CaplInstance*)m_apprWOList.GetItemData(nItem);
				if(inst)
					m_wf_mgr->ShowNotes(inst);
			}
		}
	}
}

void CCommonETDialog::OnCbnSelchangeRoleCombo()
{
	// TODO: Add your control notification handler code here
	OnSelchangeEtConnector() ;
}
