// resVedomDlg.cpp : implementation file
//

#include "stdafx.h"
#include "resVedomDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CResVedomDlg dialog

CResVedomDlg::CResVedomDlg(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CResVedomDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CResVedomDlg)
	m_id = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_reportCtrl.SetUniqueName(_T("apl_psm_resVed"));
	m_api=0;
	m_pdf=0;
	m_bp=0;
	m_context=0;
	m_sn="";
	m_time.SetStatus(COleDateTime::null);
	m_iAlgType=0;
}

void CResVedomDlg::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CResVedomDlg)
	DDX_Control(pDX, IDC_PRIORITY, m_priority_ctrl);
	DDX_Control(pDX, IDCANCEL, m_BtnCancel);
	DDX_Control(pDX, IDC_BTN_SELECT_COLUMN, m_BtnSelColumn);
	DDX_Control(pDX, ID_SELECT_CHARACTERYSTIC_SET, m_BtnSelChar);
	DDX_Control(pDX, IDC_SAVE, m_BtnSave);
	DDX_Control(pDX, ID_GO, m_BtnGo);
	DDX_Control(pDX, IDC_DATE, m_time_ctrl);
	DDX_Control(pDX, IDC_SN, m_sn_ctrl);
	DDX_Control(pDX, IDC_FILTER, m_filter_ctrl);
	DDX_Control(pDX, IDC_CONTEXT, m_context_ctrl);
	DDX_Control(pDX, IDC_CHOSEN_TYPES, m_chosenResTypes);
	DDX_Control(pDX, IDC_RES_TYPES, m_resTypes);
	DDX_Control(pDX, IDC_ACTION_ID, m_actionId);
	DDX_Text(pDX, IDC_ACTION_ID, m_id);
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_ALGORITHM_TYPE, m_algorithm_type_ctrl);
}

BEGIN_MESSAGE_MAP(CResVedomDlg, CaplResizableDialog)
	//{{AFX_MSG_MAP(CResVedomDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_ADD_RES_TYPE, OnAddResType)
	ON_BN_CLICKED(IDC_REMOVE_RES_TYPE, OnRemoveResType)
	ON_BN_CLICKED(ID_GO, OnGo)
	ON_BN_CLICKED(IDC_SAVE, OnSave)
	ON_BN_CLICKED(IDC_ADD_ALL_RES_TYPE, OnAddAllResType)
	ON_BN_CLICKED(IDC_REMOVE_ALL_RES_TYPE, OnRemoveAllResType)
	ON_BN_CLICKED(IDC_FILTER, OnFilter)
	ON_BN_CLICKED(IDC_BTN_SELECT_COLUMN, OnBtnSelectColumn)
	ON_BN_CLICKED(ID_SELECT_CHARACTERYSTIC_SET, OnSelectCharacterysticSet)
	ON_LBN_DBLCLK(IDC_RES_TYPES, OnDblclkResTypes)
	ON_LBN_DBLCLK(IDC_CHOSEN_TYPES, OnDblclkChosenTypes)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CResVedomDlg message handlers

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

	// Add "About..." menu item to system menu.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here

	m_algorithm_type_ctrl.ResetContent();
	m_algorithm_type_ctrl.AddString(APL_T("Сложение"));
	m_algorithm_type_ctrl.AddString(APL_T("Максимум"));
	m_algorithm_type_ctrl.SelectString(-1,APL_T("Сложение"));


	//RECT rect={5,5,10,10};
	//m_reportCtrl.Create(WS_VISIBLE|WS_CHILD|WS_BORDER|LVS_SHOWSELALWAYS|LVS_SINGLESEL,rect,this,IDC_ST_LIST1);
	m_reportCtrl.CreateFromStatic(IDC_ST_LIST,this,0,true);

//	m_st_list.GetWindowRect(&rect);
//	ScreenToClient(&rect);
//	m_reportCtrl.MoveWindow(&rect);

	ListView_SetExtendedListViewStyle(m_reportCtrl.m_hWnd,
		ListView_GetExtendedListViewStyle(m_reportCtrl.m_hWnd)
			|LVS_EX_UNDERLINECOLD |LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);

	//прикрепляем "якоря" чтобы при изменении размеров диалога соблюдались положение и пропорции элементов
	AddAnchor(IDC_ACTION_ID,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_ID_TEXT,TOP_LEFT);
	AddAnchor(IDC_CHOSEN_TYPES,TOP_LEFT,TOP_CENTER);
	AddAnchor(IDC_CHOSEN_TYPES_TEXT,TOP_LEFT);
	AddAnchor(IDC_RES_TYPES,TOP_CENTER,TOP_RIGHT);
	AddAnchor(IDC_RES_TYPES_TEXT,TOP_CENTER);
	AddAnchor(IDC_ALGORITHM_TYPE,TOP_RIGHT);
	AddAnchor(IDC_ALGORITHM_TEXT,TOP_RIGHT);

	AddAnchor(IDC_CONTEXT,TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_DATE,TOP_LEFT);
	AddAnchor(IDC_SN_TEXT,TOP_LEFT);
	AddAnchor(IDC_SN,TOP_LEFT);
	AddAnchor(IDC_FILTER,TOP_RIGHT);
	
	AddAnchor(IDC_ADD_ALL_RES_TYPE,TOP_CENTER);
	AddAnchor(IDC_ADD_RES_TYPE,TOP_CENTER);
	AddAnchor(IDC_REMOVE_RES_TYPE,TOP_CENTER);
	AddAnchor(IDC_REMOVE_ALL_RES_TYPE,TOP_CENTER);

	AddAnchor(IDC_ST_LIST,TOP_LEFT, BOTTOM_RIGHT);

	AddAnchor(ID_SELECT_CHARACTERYSTIC_SET,BOTTOM_LEFT);
	AddAnchor(IDC_BTN_SELECT_COLUMN,BOTTOM_LEFT);
	AddAnchor(IDC_SAVE,BOTTOM_LEFT);
	AddAnchor(ID_GO,TOP_LEFT);
	AddAnchor(IDCANCEL,BOTTOM_RIGHT);

	//заголовки столбцов
	RECT lpRect;
	m_reportCtrl.GetWindowRect(&lpRect);
	long width=lpRect.right-lpRect.left-5;
	m_reportCtrl.InsertColumn(0,APL_T("Тип ресурса"),LVCFMT_LEFT,(long)(width *.15));
	m_reportCtrl.InsertColumn(1,APL_T("Обозначение"),LVCFMT_LEFT,(long)(width *.25));
	m_reportCtrl.InsertColumn(2,APL_T("Наименование"),LVCFMT_LEFT,(long)(width *.3));
	m_reportCtrl.InsertColumn(3,APL_T("Версия"),LVCFMT_LEFT,(long)(width *.1));
	m_reportCtrl.InsertColumn(4,APL_T("Количество"),LVCFMT_RIGHT,(long)(width *.1));
	m_reportCtrl.SetColumnNumeric(4);
	m_reportCtrl.InsertColumn(5,APL_T("Ед.изм."),LVCFMT_RIGHT,(long)(width *.1));

	// иконки на кнопки	
	m_BtnCancel.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_BtnCancel.SetFlat(FALSE);
	m_BtnSelColumn.SetIcon(GetAplTableIco(APL_TABLE_WIDTH));
	m_BtnSelColumn.SetFlat(FALSE);
	m_BtnSelChar.SetFlat(FALSE);
	m_BtnSelChar.SetIcon(GetAplTableIco(APL_TABLE_SELECT_CHAR));
	m_BtnSave.SetIcon(GetAplTableIco(APL_TABLE_SAVE));
	m_BtnSave.SetFlat(FALSE);
	m_BtnGo.SetIcon(GetAplStdIco16(APLSTDICO_PLAY));
	m_BtnGo.SetFlat(FALSE);


	if(!GetBPResourceTypes())//получим все возможные типы ресурсов
	{
		AfxMessageBox(APL_T("Не удалось получить типы ресурсов для действий!"));
	}
	if(m_bp) //пользователь выбрал бизнес-процесс - установим его id и наименование
	{
		CString bp_name="";
		m_api->m_data.GetAttr(m_bp,m_api->m_bp_mgr.a_bp_id,m_id);
		m_api->m_data.GetAttr(m_bp,m_api->m_bp_mgr.a_bp_name,bp_name);
		if(bp_name!="") m_id+=" : "+bp_name;
		m_filter_ctrl.EnableWindow(FALSE);
	}
	else if(m_pdf) //пользователь выбрал версию изделия
	{
		m_context_ctrl.SetWindowText(APL_T("все контексты"));
		CString pdf_id=_T(""),prd_name=_T("");
		m_api->m_data.GetAttr(m_pdf,m_api->m_prd_mgr.a_pdf_id,pdf_id);
		CaplInstance *tempInst=0;
		m_api->m_data.GetAttr(m_pdf,m_api->m_prd_mgr.a_pdf_prd,tempInst);
		if(tempInst)
		{
			m_api->m_data.GetAttr(tempInst,m_api->m_prd_mgr.a_prd_id,m_id);
			m_api->m_data.GetAttr(tempInst,m_api->m_prd_mgr.a_prd_name,prd_name);
		}
		if(pdf_id!=_T("")) m_id+=_T(" - ")+pdf_id;
		if(prd_name!=_T(""))m_id+=_T(" : ")+prd_name;
	}
	m_priority_ctrl.SetWindowText(_T("0"));
	UpdateData(FALSE);
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CResVedomDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CaplResizableDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CResVedomDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CaplResizableDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CResVedomDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CResVedomDlg::OnClose() 
{
	CaplResizableDialog::EndDialog(IDOK);
}

bool CResVedomDlg::GetBPResourceTypes()//чтение возможных типов ресурсов 
{
	aplExtent ext;
	int i;
	
	CaplLoadData loadD(&m_api->m_data,DEF_SOURCE);
	loadD.ClearQuery();

	i=	loadD.AddQuery('e', 0, m_api->m_bp_mgr.e_bp_res_type, 0,true);
		loadD.AddQuery('d', i, 0, m_api->m_bp_mgr.a_bp_res_type_name, true);

    if(!loadD.LoadEx())
	{
		AfxMessageBox(APL_T("Запрос характеристик не выполнился!"));
		return false;
	}
	m_api->m_data.GetEntityExtent(m_api->m_bp_mgr.e_bp_res_type,ext);
		
	i=0;
	CString resTypeName;
	bool foundActResType=false;
	int curItemNumber = m_resTypes.AddString(APL_T("не задан"));//для ресурсов с неуказанным типом
	m_resTypes.SetItemData(curItemNumber,DWORD(0));

	for(i=0; i<ext.GetSize(); i++)
	{
		foundActResType=true;
		if(m_api->m_data.GetAttr(ext[i],m_api->m_bp_mgr.a_bp_res_type_name,resTypeName))
		{
			curItemNumber = m_resTypes.AddString(resTypeName);
		}
		else
		{
			AfxMessageBox(APL_T("Не удалось получить имя ресурса!"));
			curItemNumber = m_resTypes.AddString(APL_T("не задан"));
		}
		m_resTypes.SetItemData(curItemNumber,DWORD(ext[i]));
	}
	if(!foundActResType)
	{
		AfxMessageBox(APL_T("Не удалось найти ни одного типа ресурса!"));
		return false;
	}
	m_resTypes.UpdateData(FALSE);
	m_resTypes.SetCurSel(0);
    return true;	
}

void CResVedomDlg::OnDblclkResTypes() 
{
	// TODO: Add your control notification handler code here
	OnAddResType();
}

void CResVedomDlg::OnAddResType() //добавление типа ресурсов к выбранным типам
{
	int selectedResType;
	CString resName;
	long actionResourceId;
	selectedResType=m_resTypes.GetCurSel();
	int curItemNumber;
	if(selectedResType!=LB_ERR)
	{
		m_resTypes.GetText(selectedResType,resName);
		actionResourceId=m_resTypes.GetItemData(selectedResType); 
		if(!actionResourceId)
			curItemNumber=m_chosenResTypes.InsertString(0,resName);
		else
			curItemNumber=m_chosenResTypes.AddString(resName);
		m_chosenResTypes.SetItemData(curItemNumber,actionResourceId);
		m_resTypes.DeleteString(selectedResType);
	}

	m_resTypes.UpdateData();
	m_chosenResTypes.UpdateData();	
	//установим курсор
	int elemCount=m_resTypes.GetCount();
	if(elemCount)
	{
		if(selectedResType==0)
		{
			m_resTypes.SetCurSel(0);
		}
		else
		{	
			if(selectedResType==elemCount)
			{
				m_resTypes.SetCurSel(selectedResType-1);
			}
			else
			{
				m_resTypes.SetCurSel(selectedResType);
			}
		}
	}
}

void CResVedomDlg::OnDblclkChosenTypes() 
{
	// TODO: Add your control notification handler code here
	OnRemoveResType();
}

void CResVedomDlg::OnRemoveResType() //удаление типа ресурсов из выбранных
{
	int selectedResType;
	CString resName;
	long actionResourceId;
	int curItemNumber;	
	selectedResType=m_chosenResTypes.GetCurSel();
	if(selectedResType!=LB_ERR)
	{
		m_chosenResTypes.GetText(selectedResType,resName);
		actionResourceId=m_chosenResTypes.GetItemData(selectedResType);
		if(!actionResourceId)
			curItemNumber=m_resTypes.InsertString(0,resName);
		else
			curItemNumber=m_resTypes.AddString(resName);
		m_resTypes.SetItemData(curItemNumber,actionResourceId);
		m_chosenResTypes.DeleteString(selectedResType);
	}
	
	m_resTypes.UpdateData();
	m_chosenResTypes.UpdateData();
	//установим курсор
	int elemCount=m_chosenResTypes.GetCount();
	if(elemCount)
	{
		if(selectedResType==0)
		{
			m_chosenResTypes.SetCurSel(0);
		}
		else
		{	
			if(selectedResType==elemCount)
			{
				m_chosenResTypes.SetCurSel(selectedResType-1);
			}
			else
			{
				m_chosenResTypes.SetCurSel(selectedResType);
			}
		}
	}
}

void CResVedomDlg::OnGo() 
{
	CString sAlgType; m_algorithm_type_ctrl.GetWindowText(sAlgType);
	if(sAlgType==APL_T("Максимум")) m_iAlgType=1; else m_iAlgType=0;

	if(!m_chosenResTypes.GetCount())
	{
		MessageBox(APL_T("Необходимо выбрать типы ресурсов!"),APL_T("Ошибка"), MB_OK|MB_ICONEXCLAMATION);
		return;
	}
	UpdateData();
	m_extBPs.Clear();
	m_extBPResources.Clear();
	aplExtent extA;
	if(m_bp)//получаем все ресурсы для выбранного бизнес-процесса (рекурсивно для всех подпроцессов)
	{
		extA.Add(m_bp);
		long thread=aplStartWaitDlg(APL_T("Идет формирование отчета ..."));
		GetAllBPResources(extA);//получим все ресурсы бизнес-процессов по выбранному (рекурсивно)
		m_finTable.RemoveAll();
		FillFinalStruct();//сформируем окончательный массив для вывода с учетом суммирования одинаковых ресурсов
		aplEndWaitDlg(thread);
	}
	else if(m_pdf)//для версии изделия получаем его состав, затем для ассоциированных с входящими в сборку изделиями
				  //бизнес-процессов получаем все ресурсы
	{
		if(m_pdf->GetAccessmode()>aplRO) {AfxMessageBox(APL_T("Нет доступа!"),MB_OK|MB_ICONSTOP);return;}
		aplExtent m_extRels,ext,ext_pdf;
		aplRealArray pdf_count_array;
		aplExtent ext_unit;
		CString m_time_s="";
		m_time_ctrl.GetWindowText(m_time_s);
		if(m_time_s!="") aplDate2String(m_time,m_time_s);
		m_api->m_prd_mgr.DisassemblyProduct(m_context,m_pdf,m_extRels,ext, pdf_count_array, ext_unit,m_time_s,m_sn);

		int i;
		long thread=aplStartWaitDlg(APL_T("Идет формирование отчета ..."));
		aplRealArray unique_pdf_count_array;
		ext_pdf.Add(m_pdf);
		unique_pdf_count_array.Add(1);
		//в полученном составе изделия (pdf) могут дублироваться на разных уровнях сборки 
		//нужно просуммировать все вхождения одинаковых изделий
		for(i=0;i<m_extRels.GetSize();i++)
		{
			CaplInstance *pdf;
			m_api->m_data.GetAttr(m_extRels[i],m_api->m_prd_mgr.a_pdr_r_ted,pdf);
			if(!pdf) continue;
			int index=ext_pdf.Find(pdf);
			if(index>-1) 
			{
				unique_pdf_count_array[index]+=pdf_count_array[i];
			}
			else
			{
				ext_pdf.Add(pdf);
				unique_pdf_count_array.Add(pdf_count_array[i]);
			}
		}
		aplExtent ext_bp_rel;
		m_api->m_bp_mgr.FindAssociatedBP(ext_pdf,extA,ext_bp_rel,m_context);
		aplExtent ext_mat_rel,ext_mat;
		m_api->m_prd_mgr.LoadAllZagotov(ext_pdf,ext_mat_rel,ext_mat,true,true);
		GetAllBPResources(extA);//получим все ресурсы бизнес-процессов по выбранным (рекурсивно)
		m_finTable.RemoveAll();
		m_extBPs.Clear();
		CString buf;
		m_priority_ctrl.GetWindowText(buf);
		int chosen_priority=_atoi(buf);
		for(i=0;i<ext_pdf.GetSize();i++)
		{
			ext_bp_rel.Clear();extA.Clear();
			m_api->m_bp_mgr.FindAssociatedBP(ext_pdf[i],extA,ext_bp_rel,m_context,false);
			CaplInstance *tp_with_chosen_priority=0;
			CaplInstance *tp_with_lest_priority=0;
			CaplInstance *tp_without_zagotov=0;
			CaplInstance *tp=0;
			int lest_priority=INT_MAX;
			for(int j=0;j<ext_bp_rel.GetSize();j++)
			{
				CaplInstance *zagotov_rel=0;
				m_api->m_data.GetAttr(ext_bp_rel[j],m_api->m_bp_mgr.a_bp_ref_zagotov,zagotov_rel);
				CaplInstance *bp;
				m_api->m_data.GetAttr(ext_bp_rel[j],m_api->m_bp_mgr.a_bp_ref_process,bp);
				int priority=-1;
				if(zagotov_rel) 
				{
					m_api->m_data.GetAttr(zagotov_rel,m_api->m_prd_mgr.a_make_from_ranking,priority);
				}
				else
				{
					tp_without_zagotov=bp;
				}
				if(chosen_priority==priority)
				{
					tp_with_chosen_priority=bp;	
					break;
				}
				if(priority!=-1 && priority<lest_priority)
				{
					lest_priority=priority;
					tp_with_lest_priority=bp;
				}
			}
			if(tp_with_chosen_priority) tp=tp_with_chosen_priority;//если найден тп с заданным юзером приоритетом, используем его
			else if(tp_with_lest_priority) tp=tp_with_lest_priority;//иначе, если есть тп с наименьшим приоритетом, используем его
			else tp=tp_without_zagotov;//иначе используем тп с незаданным материалом
			if(tp)
			{
				m_extBPResources.Clear();
				aplExtent ext_tp;
				ext_tp.Add(tp);
				GetAllBPResources(ext_tp,false);
				FillFinalStruct(ext_pdf[i],unique_pdf_count_array[i]);
			}
		}
		aplEndWaitDlg(thread);
	}

	if(!SetOut())//выведем на экран
	{
		AfxMessageBox(APL_T("Такие ресурсы не найдены!"));
	}
}

void CResVedomDlg::GetAllBPResources(aplExtent &ext,bool from_base)
{
	if(from_base && ext.GetSize()>0)
	{
		int i_res,i_lok,i_ob,i_rt,i_pdf;
		CaplLoadData loadD(&m_api->m_data,DEF_SOURCE);		
		loadD.ClearQuery();
		
		for(int j=0;j<ext.GetSize();j++)
		{
			if(!ext[j]) continue;
			if(ext[j]->GetAccessmode()>aplRO) {AfxMessageBox(APL_T("Нет доступа к данным бизнес-процесса!"),MB_OK|MB_ICONSTOP);continue;}
			loadD.AddQuery(0,ext[j],true);
			m_extBPs.Add(ext[j]);
		}
		//загрузка атрибутов бизнес-процессов и ресурсов
				//атрибуты бизнес-процессов
				loadD.AddQuery('d', 0,  0, m_api->m_bp_mgr.a_bp_elements, true,true);
		i_res=	loadD.AddQuery('d', 0,  0, m_api->m_bp_mgr.a_bp_res, true,true);
				//атрибуты текущих (редактируемых) версий бизнес-процессов,
		i_lok=	loadD.AddQuery('d', 0,  0, m_api->m_bp_mgr.a_bp_lock, true,true);
				loadD.AddQuery('d', i_lok,  0, m_api->m_bp_mgr.a_bp_ver_elements, true,true);
				loadD.AddQuery('d', i_lok,  0, m_api->m_bp_mgr.a_bp_ver_author, true,true);
				loadD.AddQuery(i_res,'d', i_lok,  0, m_api->m_bp_mgr.a_bp_ver_res, true,true);
				//атрибуты ресурсов
		i_rt =	loadD.AddQuery('d', i_res,  0, m_api->m_bp_mgr.a_bp_res_type, true,true);
				loadD.AddQuery('d', i_res,  0, m_api->m_bp_mgr.a_bp_res_unit, true,true);
				loadD.AddQuery('d', i_res,  0, m_api->m_bp_mgr.a_bp_res_process, true,true);
		i_ob =  loadD.AddQuery('d',  i_res,  0, m_api->m_bp_mgr.a_bp_res_object, true,true);
				//атрибуты объектов, на которые ссылаются ресурсы
				// если это pdf
				loadD.AddQuery('d', i_ob, 0, m_api->m_prd_mgr.a_pdf_prd,true,true);
				// если это lot
		i_pdf=	loadD.AddQuery('d', i_ob, 0, m_api->m_prd_inst_mgr.a_lot_pdf,true,true);
				loadD.AddQuery('d', i_pdf, 0, m_api->m_prd_mgr.a_pdf_prd,true,true);
				// если это prd_inst
		i_pdf=	loadD.AddQuery('d', i_ob, 0, m_api->m_prd_inst_mgr.a_prd_inst_pdf,true,true);
				loadD.AddQuery('d', i_pdf, 0, m_api->m_prd_mgr.a_pdf_prd,true,true);

//		ii =	loadD.AddQuery('d', i_res, 0, m_api->m_prd_inst_mgr.a_lot_size, true);
//				loadD.AddQuery('d', ii, 0, m_api->m_prd_inst_mgr.a_mwu_val, true);
//				loadD.AddQuery('d', ii, 0, m_api->m_prd_inst_mgr.a_mwu_unit, true);
			  
		if(!loadD.LoadEx())
		{
			AfxMessageBox(APL_T("Запрос не выполнился!"));
			return;
		}
	}

	int i, j;
	aplExtent extA;
	for(j=0;j<ext.GetSize();j++)
	{
		if(!ext[j]) continue;
		if(ext[j]->GetAccessmode()>aplRO) continue;
		CaplAggr aggr_res;
		CaplInstance *lock=m_api->m_bp_mgr.CheckMyLock(ext[j],false);
		if(lock)//если текущий пользователь взял на редактирование этот бизнес-процесс,
				//список ресурсов нужно брать редактируемый (у версии-локера)
			m_api->m_data.GetAttr(lock,m_api->m_bp_mgr.a_bp_ver_res,aggr_res);
		else   //берем обычный список ресурсов
			m_api->m_data.GetAttr(ext[j],m_api->m_bp_mgr.a_bp_res,aggr_res);
		for(i=0;i<aggr_res.GetSize();i++)
		{
			CaplInstance *res=0;
			aggr_res.GetByIndex(i,res);
			if(!res) continue;
			if(res->GetAccessmode()>aplRO) {AfxMessageBox(APL_T("Нет доступа к данным ресурса!"),MB_OK|MB_ICONSTOP);continue;}
			if(FilterResourcesByType(res))//отфильтруем ресурсы по выбранным пользователем типам
				m_extBPResources.Add(res);
		}
		CaplAggr cElements;
		if(lock)//если текущий пользователь взял на редактирование этот бизнес-процесс,
				//список подпроцессов нужно брать редактируемый
			m_api->m_data.GetAttr(lock,m_api->m_bp_mgr.a_bp_ver_elements,cElements);
		else    //берем обычный список подпроцессов
			m_api->m_data.GetAttr(ext[j],m_api->m_bp_mgr.a_bp_elements,cElements);
		for(i=0;i<cElements.GetSize();i++)
		{
			CaplInstance *cBPInstance=0;
			cElements.GetByIndex(i,cBPInstance);
			if(cBPInstance)	extA.Add(cBPInstance);
		}
	}
	if(extA.GetSize()) GetAllBPResources(extA,from_base);
		
}

bool CResVedomDlg::FilterResourcesByType(CaplInstance *resource)//фильтрация ресурсов в зависимости от выбранных пользователем типов
{
	if(!resource) return false;
	CaplInstance *actResType=0;
	m_api->m_data.GetAttr(resource,m_api->m_bp_mgr.a_bp_res_type,actResType);
	int i=0;

	bool foundActResType=false;
	while(i<m_chosenResTypes.GetCount())
	{
		CaplInstance *chosenResType=(CaplInstance*)m_chosenResTypes.GetItemData(i);
		if(chosenResType==actResType)
		{
			return true;
		}
		i++;
	}	
	return false;
}

void CResVedomDlg::FillFinalStruct(CaplInstance *pdf,double pdf_amount) //заполнение окончательного массива со списком ресурсов с суммированием одинаковых
{
	int i,j;
	finalVedomost tempVed;
	bool foundSame;
	CaplInstance* inst=0;

	for(i=0;i<m_extBPResources.GetSize();i++)
	{
		tempVed.resource=m_extBPResources[i];

		m_api->m_data.GetAttr(tempVed.resource,m_api->m_bp_mgr.a_bp_res_unit,tempVed.unit);
		m_api->m_data.GetAttr(tempVed.resource,m_api->m_bp_mgr.a_bp_res_val,tempVed.resMeasurement);
		m_api->m_data.GetAttr(tempVed.resource,m_api->m_bp_mgr.a_bp_res_object,tempVed.obj);
		m_api->m_data.GetAttr(tempVed.resource,m_api->m_bp_mgr.a_bp_res_type,tempVed.resourceType);
		if(tempVed.resourceType){
			m_api->m_data.GetAttr(tempVed.resourceType,m_api->m_bp_mgr.a_bp_res_type_name,tempVed.resTypeName);
		}else{
			tempVed.resTypeName="";
		}
		//if(pdf) // ЯАИ: проверка убрана чтобы можно было посчитать просто по БП
		{
			tempVed.pdf=pdf;

			if(0==pdf  && 0==pdf_amount) pdf_amount=1; // ЯАИ: проверка убрана чтобы можно было посчитать просто по БП

			tempVed.pdfMeasurement=pdf_amount;
			if(m_iAlgType==0)	tempVed.resMeasurement*=pdf_amount;
		}
		foundSame=false;
		for(j=0;j<m_finTable.GetSize();j++)
		{
			finalVedomost &fvj=m_finTable[j];

			if(fvj.obj==tempVed.obj)
			{
				if(fvj.unit==tempVed.unit)//если id объектов ресурса и их единица измерения совпадают, 
														//не добавляем в отчет новый ресурс, а суммируем количество
				{
					//в зависимости от типа расчета, суммируем ресурсы либо ищем максимум
					if(0==m_iAlgType)	//сумма
					{
						fvj.resMeasurement+=tempVed.resMeasurement;
					}
					else //максимум
					{
						if(fvj.resMeasurement<tempVed.resMeasurement)
							fvj.resMeasurement=tempVed.resMeasurement;
					}
					foundSame=true;
					if(0==fvj.pExtUsedPdfs) fvj.pExtUsedPdfs=new aplExtent;
					fvj.pExtUsedPdfs->Add(pdf);
					break;
				}
			}
			
		}
		if(!foundSame)
		{
			int j=m_finTable.Add(tempVed);
			finalVedomost &fvj=m_finTable[j];
			if(0==fvj.pExtUsedPdfs) fvj.pExtUsedPdfs=new aplExtent;
			fvj.pExtUsedPdfs->Add(pdf);
		}
	}
}

void CResVedomDlg::OnSave() //сохранение данных отчета в файл
{
	UpdateData();
	CString fileName;

	//if((m_extBPs[0])&&(m_reportCtrl.GetItemCount()))
	if(m_reportCtrl.GetItemCount())
		{
		fileName=APL_T("Ведомость ресурcа(ов) для ")+m_id;
		if(apl_SaveListCtrlToFile(&m_reportCtrl,fileName))
			MessageBox(APL_T("Отчет успешно сохранен!"),APL_T("Сообщение"), MB_OK|MB_ICONINFORMATION);
		}
	else
		AfxMessageBox(APL_T("Нет данных для сохранения!"));
		

}

void CResVedomDlg::OnCancel() 
{
	OnClose();
	CaplResizableDialog::OnCancel();
}

bool CResVedomDlg::SetOut()//вывод на экран
{
	int i,j;
	CString sAddText,sPrdId;
	m_Items.Clear();
	for(i=0;i<m_finTable.GetSize();i++){

		sAddText="";
		finalVedomost &fvi=m_finTable[i];

		if(0!=fvi.pExtUsedPdfs)
		{
			for(j=0;j<fvi.pExtUsedPdfs->GetSize();j++)
			{
				CaplInstance *pdf=(*(fvi.pExtUsedPdfs))[j];
				if(0==pdf) sPrdId.Empty();
				else m_api->GetItemName(pdf,sPrdId);

				if(sPrdId!="")
				{
					if(sAddText!="") sAddText+="; ";
					sAddText+=sPrdId;
				}
			}
		}
		m_Items.Add(new SItemColumnData(fvi.obj,fvi.resMeasurement,fvi.unit,fvi.resTypeName,sAddText));
	}

	m_reportCtrl.m_api=m_api;
	m_reportCtrl.SaveColumnWidths();
	m_reportCtrl.SetResourceMode(true);
	m_reportCtrl.SetAdditionalColumnName(APL_T("Тип ресурса"),APL_T("Для изделий"));
	m_reportCtrl.SetData(m_Items);

	m_reportCtrl.VisibleColumnAdd(0,OBJ_COL_ADD_TEXT);
	m_reportCtrl.VisibleColumnRemove(0,OBJ_COL_INSTANCE_ID);
	m_reportCtrl.VisibleColumnRemove(0,OBJ_COL_DESCRIPT);
	m_reportCtrl.VisibleColumnRemove(0,OBJ_COL_CODE_OBJ);
	m_reportCtrl.VisibleColumnRemove(0,OBJ_COL_CODE_VER);

	m_reportCtrl.FillTable();
	return true;
		

}

void CResVedomDlg::OnAddAllResType() //добавление всех типов ресурсов в выбранные 
{
	int i;
	CString resName;
	long actionResourceId;
	int curItemNumber;
	int elemCount=m_resTypes.GetCount();
	for(i=0;i<elemCount;i++)
	{
		m_resTypes.GetText(i,resName);
		actionResourceId=m_resTypes.GetItemData(i); 
		curItemNumber=m_chosenResTypes.AddString(resName);
		m_chosenResTypes.SetItemData(curItemNumber,actionResourceId);
	}
	for(i=0;i<elemCount;i++)
	    m_resTypes.DeleteString(0);
	m_resTypes.UpdateData(FALSE);
	m_chosenResTypes.UpdateData(FALSE);	
	//установим курсор
	elemCount=m_chosenResTypes.GetCount();
	if(elemCount)
		m_chosenResTypes.SetCurSel(0);

}

void CResVedomDlg::OnRemoveAllResType() //удаление всех типов ресурсов из выбранных
{
	int i;
	CString resName;
	long actionResourceId;
	int curItemNumber;
	int elemCount=m_chosenResTypes.GetCount();
	for(i=0;i<elemCount;i++)
		{
		m_chosenResTypes.GetText(i,resName);
		actionResourceId=m_chosenResTypes.GetItemData(i); 
		curItemNumber=m_resTypes.AddString(resName);
		m_resTypes.SetItemData(curItemNumber,actionResourceId);
		}
	for(i=0;i<elemCount;i++)
	    m_chosenResTypes.DeleteString(0);
	m_resTypes.UpdateData();
	m_chosenResTypes.UpdateData();	
	//установим курсор
	elemCount=m_resTypes.GetCount();
	if(elemCount)
		m_resTypes.SetCurSel(0);
}

void CResVedomDlg::OnFilter() //вызывает диалог фильтрации состава изделия по контексту, дате и серийному номеру
{							  //и устанавливает соответственные член-данные
	if(m_time.GetStatus()!=COleDateTime::valid) m_time.SetStatus(COleDateTime::null);
	CaplInstance *new_cont=0;
	if(m_api->m_prd_mgr.SelectDateSN(m_sn,m_time,m_context,&new_cont))
	{
		m_sn_ctrl.SetWindowText(m_sn);
		CString buf="";
		if(m_time.GetStatus()==COleDateTime::valid)
			buf=m_time.Format(_T("%d.%m.%Y  %H:%M:%S"));
		m_time_ctrl.SetWindowText(buf);
		buf="";
		m_context=new_cont;
		if(m_context)
		{
			aplExtent aggr;
			aggr.Add(m_context);
			m_api->m_prd_mgr.PrintItemContextInString(aggr,buf);
		}
		else
			buf="все контексты";
		m_context_ctrl.SetWindowText(buf);
	}
}

void CResVedomDlg::OnBtnSelectColumn() 
{
	// TODO: Add your control notification handler code here
	m_reportCtrl.SelectColumnsOrder(0);
	
}

void CResVedomDlg::OnSelectCharacterysticSet() 
{
	// TODO: Add your control notification handler code here
	m_reportCtrl.SelectCharacterysticSet(0);

}


