<?php


if (!class_exists('Lib')) die('404');


function fun_PROCES_INIT() {
	$redirect = "?task=".App::get_task();
	$msg = '';

	$id_proces = V::get('id_proces', '', $_REQUEST, 'int');
	if ($id_proces <= 0) {
		App::add_error("Wrong ID!");
		App::redirect($redirect, $msg);
		return;
	}

	$p = DB::get_by_id( 'CRM_PROCES', $id_proces );
	if (!$p) {
		App::add_error("Process ".$id_proces." not exists!");
		App::redirect($redirect, $msg);
		return;
	}

	// TODO: check if proces $p is PROCES_INIT
	$db = DB::getDB();
	Lib::loadClass('ProcesLogDao');
	$procesLogDao = new ProcesLogDao($db);
	$new_id = $procesLogDao->proces_log_init(User::getID(), User::getName(), $p->ID);

	if ($new_id > 0) {
		App::add_msg("Rozpoczeto proces ".$p->ID." (LOG ID ".$new_id.")");
		$redirect = "?task=PROCES_LOG&_log_id=".$new_id;
	}
	else {
		App::add_error("Nie udalo sie rozpoczac procesu!");
	}
	App::redirect($redirect, $msg);
}


/**
 * Go to next step - next Proces.
 * @param _log_id
 * @param _next_step_id
 */
function fun_PROCES_LOG_STEP_NEXT() {
	$redirect = "?task=".App::get_task();
	$msg = '';

	$log_id = V::get('_log_id', 0, $_REQUEST, 'int');
	if ($log_id <= 0) {
		App::add_error("Wrong Log ID!");
		App::redirect($redirect, $msg);
		return;
	}

	$redirect .= "&_log_id=" . $log_id;

	$next_id = V::get('_next_step_id', 0, $_REQUEST, 'int');
	if ($next_id <= 0) {
		App::add_error("Wrong next step ID!");
		App::redirect($redirect, $msg);
		return;
	}

	$db = DB::getDB();

	Lib::loadClass('ProcesLogDao');
	$procesLogDao = new ProcesLogDao($db);

	$modelLog = $procesLogDao->get_by_id($log_id);
	if (!$modelLog) {
		App::add_error("Error Log [$log_id] not exists!");
		App::redirect($redirect, $msg);
		return;
	}

	if ($modelLog->allow_next_step($next_id)) {
		if ($modelLog->go_to_next_step($next_id)) {
			// ok next step is set
		} else {
			App::add_error("Error at go to next step!");
		}
	} else {
		App::add_error("Next step is not allowed!");
	}
	App::redirect($redirect, $msg);
}


/**
 * Go to next step wsk - next Proces.
 * @param _log_id
 * @param _next_step_wsk_id
 */
function fun_PROCES_LOG_STEP_WSK_NEXT() {
	$redirect = "?task=".App::get_task();
	$msg = '';

	$log_id = V::get('_log_id', 0, $_REQUEST, 'int');
	if ($log_id <= 0) {
		App::add_error("Wrong Log ID!");
		App::redirect($redirect, $msg);
		return;
	}

	$redirect .= "&_log_id=" . $log_id;

	$next_wsk_id = V::get('_next_step_wsk_id', 0, $_REQUEST, 'int');
	if ($next_wsk_id <= 0) {
		App::add_error("Wrong next step wsk ID!");
		App::redirect($redirect, $msg);
		return;
	}

	$db = DB::getDB();

	Lib::loadClass('ProcesLogDao');
	$procesLogDao = new ProcesLogDao($db);

	$modelLog = $procesLogDao->get_by_id($log_id);
	if (!$modelLog) {
		App::add_error("Error Log [$log_id] not exists!");
		App::redirect($redirect, $msg);
		return;
	}

	if ($modelLog->allow_next_step_wskaznik($next_wsk_id)) {
		if ($modelLog->go_to_next_step_wskaznik($next_wsk_id)) {
			// ok next step is set
		} else {
			App::add_error("Error at go to next step wsk!");
		}
	} else {
		App::add_error("Next step wsk is not allowed!");
	}
	App::redirect($redirect, $msg);
}


/**
 * @param str $_GET['task']
 * @param int $_GET['_log_id']
 */
function fun_PROCES_LOG_QUIT() {
	// TODO: quit proces only if has no next steps and has nothing to do
	$redirect = "?task=".App::get_task();
	$msg = '';

	$log_id = V::get('_log_id', 0, $_REQUEST, 'int');
	if ($log_id <= 0) {
		App::add_error("Wrong Log ID!");
		App::redirect($redirect, $msg);
		return;
	}

	$redirect .= "&_log_id=" . $log_id;

	$db = DB::getDB();

	Lib::loadClass('ProcesLogDao');
	$procesLogDao = new ProcesLogDao($db);

	$modelLog = $procesLogDao->get_by_id($log_id);
	if (!$modelLog) {
		App::add_error("Error Log [$log_id] not exists!");
		App::redirect($redirect, $msg);
		return;
	}

	$next_step = $modelLog->get_next_step();
	if ($modelLog->allow_end()) {
		if ($modelLog->go_to_end()) {
			App::add_msg("Zakończono proces");
		} else {
			App::add_error("Zakończenie procesu nie powiodło się");
		}
	} else {
		App::add_error("Quit is not allowed!");
	}
	App::redirect($redirect, $msg);
}


/**
 * Save current edit (ProcesLogEdit).
 * @param _log_id
 * @param _log_wsk_id
 * @param _id_key
 * @param _tbl_zasob_id - TODO: get from DB by _log_wsk_id ?
 * @param v-{$field} - form field values
 * @param f-{$field} - table filter values
 * @param f-_order_by
 * @param f-_order_desc
 * @param f-_offset
 * @param f-_limit
 * @param _action - what to do - search for rows, save edit form
 */
function fun_PROCES_STEP_SAVE() {
	DEBUG_S(1, "POST:", $_POST, __FILE__, __FUNCTION__, __LINE__);
	$log_id = V::get('_log_id', 0, $_REQUEST, 'int');
	if ($log_id <= 0) {
		echo '<p style="err">' . "Error: Proces log " . $log_id . " not exists!" . '</p>';
		return;
	}

	$db = DB::getDB();
	Lib::loadClass('ProcesLogDao');

	$procesLogDao = new ProcesLogDao($db);

	$modelLog = $procesLogDao->get_by_id($log_id);
	DEBUG_S(1, "Log($log_id):", $modelLog, __FILE__, __FUNCTION__, __LINE__);
	if (!$procesLogDao->check_access($modelLog, User::getID(), User::getGroupsIds())) {
		echo '<p style="err">' . "Error: Brak dostępu!" . '</p>';
		return;
	}

	$current_edit = $modelLog->get_current_edit();
	if (!$current_edit) {
		echo '<p style="err">' . "Error: Proces log current_edit not set!" . '</p>';
		return;
	}

	// save filters:
	$current_edit->set_filters_from_request();
	$current_edit->set_values_from_request();

	// set _id_key if isset
	$_id_key = V::get('_id_key', 0, $_REQUEST, 'int');
	if ($_id_key) {
		$current_edit->set_id_key($_id_key);
	}

	// execute action
	$_action = V::get('_action', '', $_REQUEST);
	switch ($_action) {
		case 'edit_back':
			// back to table view - remove _id_key
			$current_edit->set_id_key(0);
			break;
		case 'save_edit':
			// _save_row = Zapisz
			// TODO: require _id_key
			$rowDao = $current_edit->action_save_edit();
			if ($rowDao) {
				// TODO: fetch save arrors from $rowDao or $current_edit->action_save_edit()
				$modelLog->set('ID_STEP_WSKAZNIK', $current_edit->get_log_wsk_id());
				$modelLog->set('A_UPDATE_ZASOB_ID', $current_edit->get_tbl_zasob_id());
				//$modelLog->set('ID_KEY', $current_edit->get_id_key());
				$modelLog->set('ID_KEY', $rowDao->get_saved_id());
				$modelLog->set('A_UPDATE_HIST_ID', $rowDao->get_saved_hist_id());
				// TODO: save ID_STEP_WSKAZNIK, ID_KEY, A_UPDATE_ZASOB_ID, A_UPDATE_HIST_ID
				$saved = $procesLogDao->save($modelLog);
				if (!$saved) {
					DEBUG_S(1, "Error save record", $procesLogDao, __FILE__, __FUNCTION__, __LINE__);
				} else {
					App::add_msg("Zmiany zapisano pomyślnie");
				}
			}
			break;
		case 'select_id_key':
			$rowModel = $current_edit->action_select_id_key();
			if ($rowModel) {
				// TODO: fetch save arrors from $rowModel or $current_edit->action_select_id_key()
				$modelLog->set('ID_STEP_WSKAZNIK', $current_edit->get_log_wsk_id());
				$modelLog->set('A_UPDATE_ZASOB_ID', $current_edit->get_tbl_zasob_id());
				//$modelLog->set('ID_KEY', $current_edit->get_id_key());
				$modelLog->set('ID_KEY', $rowModel->get('ID'));
				// TODO:?: save ID_STEP_WSKAZNIK, ID_KEY, A_UPDATE_ZASOB_ID, A_UPDATE_HIST_ID
				$saved = $procesLogDao->save($modelLog);
				if (!$saved) {
					DEBUG_S(1, "Error save record", $procesLogDao, __FILE__, __FUNCTION__, __LINE__);
				} else {
					App::add_msg("Zmiany zapisano pomyślnie");
				}
			}
			break;
		case 'create':// change state to view create form
			$current_edit->set_type('create');
			break;
		case 'save_create':// try to save new record
			
			break;
		default:
			
	}

	// save state
	$current_edit->save_state();

	DEBUG_S(1, "fun_PROCES_STEP_SAVE - modelLog:", $modelLog, __FILE__, __FUNCTION__, __LINE__);
	DEBUG_S(1, "fun_PROCES_STEP_SAVE - current_edit:", $current_edit, __FILE__, __FUNCTION__, __LINE__);
}


/**
 * TODO: fun_PROCES_STEP_SAVE but Ajax request.
 */
function ajax_PROCES_STEP_SAVE() {

}


function task_PROCES_LOG() {
	$db = DB::getDB();
	Lib::loadClass('ProcesLogDao');
	Lib::loadClass('ProcesLogStepView');

	$procesLogDao = new ProcesLogDao($db);
	$view = new ProcesLogStepView();

	$log_id = V::get('_log_id', 0, $_REQUEST, 'int');
	if ($log_id <= 0) {
		echo '<p style="err">' . "Error: Proces log " . $log_id . " not exists!" . '</p>';
		return;
	}

	$modelLog = $procesLogDao->get_by_id($log_id);
	DEBUG_S(1, "Log:", $modelLog, __FILE__, __FUNCTION__, __LINE__);
	if (!$procesLogDao->check_access($modelLog, User::getID(), User::getGroupsIds())) {
		echo '<p style="err">' . "Error: Brak dostępu!" . '</p>';
		return;
	}

	$_SESSION['PROCES_LOG'] = $modelLog->get('ID');// TODO: some class method! - mv to function init?

	$view->set('proces_log', $modelLog);

	$proces_init = DB::get_by_id('CRM_PROCES', $modelLog->get('ID_PROCES_INIT'));
	$view->set('proces_init', $proces_init);

	if ($modelLog->get('ID_PROCES_INIT') != $modelLog->get('ID_STEP')) {
		$proces_step = DB::get_by_id('CRM_PROCES', $modelLog->get('ID_STEP'));
	} else {
		$proces_step = $proces_init;
	}
	$view->set('proces_step', $proces_step);

	$modelLog->is_step_finished();// TODO:??: if ?

	$wskazniki = ProcesHelper::get_wskazniki($proces_step->ID);
	$view->set('wskazniki', $wskazniki);

	// TODO: next steps - next wskaznik or next proces or END if last step in proces
	$current_edit = $modelLog->get_current_edit();
	//DEBUG_S(1, "current_edit filters 1:", array('_filters'=>$current_edit->_filters, '_nav_filters'=>$current_edit->_nav_filters), __FILE__, __FUNCTION__, __LINE__);
	if ($current_edit) {
		$current_edit->set_filters_from_request();
		//DEBUG_S(1, "current_edit filters 2:", array('_filters'=>$current_edit->_filters, '_nav_filters'=>$current_edit->_nav_filters), __FILE__, __FUNCTION__, __LINE__);
	}
	DEBUG_S(1, "current_edit", $current_edit, __FILE__, __FUNCTION__, __LINE__);
	$view->set('current_edit', $current_edit);
	//TODO: is needed? $next_edit = $procesLogDao->get_next_edit($modelLog, $wskazniki, $current_edit);

	$next_steps = array();
	DEBUG_S(1, "is_step_finished:", $modelLog->is_step_finished(), __FILE__, __FUNCTION__, __LINE__);
	if (!$current_edit) {
		if ($modelLog->get('TYPE') != 'END') {
			$next_processes = $modelLog->get_next_step();
			if (empty($next_processes)) {
				$next_steps ['quit']= App::link("zakończ", array('function_init'=>"fun_PROCES_LOG_QUIT", '_log_id'=>$log_id));
			} else {
				foreach ($next_processes as $k_proces_id => $v_desc) {
					$next_steps ['step_next']= App::link(htmlspecialchars($v_desc), array('function_init'=>"fun_PROCES_LOG_STEP_NEXT", '_log_id'=>$log_id, '_next_step_id'=>$k_proces_id));
				}
			}
		}
	} else {
		// TODO: next step wsk or proces if is finished
		if ($modelLog->is_step_finished()) {
			$next_processes = $modelLog->get_next_step();
			if (empty($next_processes)) {
				$next_steps[] = App::link("zakończ", array('function_init'=>"fun_PROCES_LOG_QUIT", '_log_id'=>$log_id));
			} else {
				foreach ($next_processes as $k_proces_id => $v_desc) {
					$next_steps[] = App::link(htmlspecialchars($v_desc), array('function_init'=>"fun_PROCES_LOG_STEP_NEXT", '_log_id'=>$log_id, '_next_step_id'=>$k_proces_id));
				}
			}
		}
		else {
			$next_step_wsk = $modelLog->get_next_step_wskaznik();
			DEBUG_S(1, "next_step_wsk:", $next_step_wsk, __FILE__, __FUNCTION__, __LINE__);
			if ($next_step_wsk) {
				$next_steps[] = App::link($next_step_wsk->get_log_wsk_id(), array('function_init'=>"fun_PROCES_LOG_STEP_WSK_NEXT", '_log_id'=>$log_id, '_next_step_wsk_id'=>$next_step_wsk->get_log_wsk_id())) . ": " . $next_step_wsk->get_step_wsk_desc();
			} else {
				// TODO: BUG
			}
		}
	}
	$view->set('next_steps', $next_steps);

	Lib::loadClass('Tree');
	Tree::show_css();

	echo '<style type="text/css">' . "
#proces-panel { margin:0 0 10px 0; padding:0 5px; background:#000; color:#fff; border-bottom:2px solid #969696; overflow:hidden; font-size:12px; }
 #proces-panel form { display:inline; }
 #proces-panel a { color:#fff; text-decoration:none; }
 #proces-panel a:hover { color:#fff; text-decoration:underline; }
#proces-content { margin:0; padding:0 14px; background:#fff; color:#333; font-size:12px; }
 #proces-content em { color:#999; }

#body_content {font-size:small;}
 #body_content .next-steps { padding:0; margin:8px 0;  border-top:3px solid #e2e2e2; background:#eee; }
  #body_content .next-steps .header { padding:0 8px; background:#e2e2e2; color:#000; }
  #body_content .next-steps .cnt { padding:8px; }

#body_content .proces-info { padding:0; margin:8px 0;  border-top:3px solid #e2e2e2; background:#eee; }
 #body_content .proces-info .header { padding:0 8px; background:#e2e2e2; color:#000; }
 #body_content .proces-info .cnt { padding:8px; }
 #body_content .proces-info .cnt .tree-wrap { background:#fff; }

#body_content .current-edit { overflow:auto; margin:6px 0; padding:8px; border-top:3px solid #e2e2e2; background:#E6E6F6; }
.page-nav .strony span { margin:0 2px; }
 .page-nav .strony a { color:#1086FA; text-decoration:none; }
 .page-nav .strony a:hover { color:#CA1818; text-decoration:underline; }

" 	. '</style>' . "\n";
	echo $view->render();
}


/**
 * @param int $_GET['_log_id']
 */
function PROCES_LOG_HIST() {
	echo 'TODO: proces log HIST';
}


function task_PROCES_LOG__bup_20121113() {
	$id_proces_log = V::get('_log_id', '', $_REQUEST, 'int');
	if ($id_proces_log <= 0) {
		echo'<p class="err">'."Wrong ID".'</p>';
		return;
	}

	$plog = DB::get_by_id( 'CRM_PROCES_LOG', $id_proces_log );
	if (!$plog) {
		echo'<p class="err">'."Process log ".$id_proces_log." not exists".'</p>';
		return;
	}

	DEBUG_S(1, 'PROCES LOG('.$plog->ID.')', $plog, __FILE__, __FUNCTION__, __LINE__);

	$id_proces = ($plog->ID_STEP)? $plog->ID_STEP : $plog->ID_PROCES_INIT;
	// pathway
	echo'<p class="box box-green">'.App::link("MENU", "?task=CRM_MENU");
		echo' - ';
		echo "Proces <b>".$plog->ID_PROCES_INIT."</b> - krok id <b>".$plog->ID_STEP."</b>";
	echo'</p>';

	$p = DB::get_by_id( 'CRM_PROCES', $id_proces );
	if (!$p) {
		echo'<p class="err box box-red">'."Process ".$id_proces." not exists".'</p>';
		return;
	}
	DEBUG_S(1, 'PROCES('.$p->ID.')', $p, __FILE__, __FUNCTION__, __LINE__);


die('.EOF L.' . __LINE__ );// TODO: dev

	$id_step = V::get('id_step', $p->ID, $_REQUEST, 'int');
	if (!$id_step) {
		$step = $p;
	} else {
		$step = DB::get_by_id( 'CRM_PROCES', $id_step );
		if (!$step) {
			echo'<p class="err box box-red">'."Process ".$id_step." not exists".'</p>';
			return;
		}
		DEBUG_S(1, 'PROCES STEP('.$step->ID.')', $step, __FILE__, __FUNCTION__, __LINE__);

		if ($step->ID != $plog->ID_STEP) {
			//TODO: check if $step is under $id_proces
			if ($step->PARENT_ID != $plog->ID_STEP) {
				echo'<p class="err box box-red">'."Blad krok ".$step->ID." nie jest nastepnym krokiem po ".$plog->ID_STEP.'</p>';
				return;
			}
			$sql_obj = new stdClass();
			$sql_obj->ID = $plog->ID;
			$sql_obj->ID_PROCES_INIT = $plog->ID_PROCES_INIT;
			$sql_obj->TYPE = 'PROCES_STEP';
			$sql_obj->ID_STEP = $step->ID;
			//TODO: $sql_obj->STEP_ROLE_ID = $step-> wskazniki type STANOWSIKO
			// lub ProcesHelper::get_allowed_role_id( $id_proces ) - search for wskaznik type STANOWISKO
			// - jesli nie istnieje to szukaj z parent az znajdziesz odpowiednie wskazniki

			$ret = DB::UPDATE_OBJ( 'CRM_PROCES_LOG', $sql_obj );
			// TODO: return codes @see DB::UPDATE_OBJ
			if ($ret != 2) {
				echo'<p class="err">'."Nie udalo sie rozpoczac kroku ".$step->ID." procesu ".$plog->ID_PROCES_INIT."".'</p>';
				DEBUG_S(5, 'DB::error', DB::error());
			} else {
				echo'<p class="ok">'."Rozpoczeto wykonywanie kroku ".$step->ID." procesu ".$plog->ID_PROCES_INIT." ";
					echo'<span class="cmnt-small">'.'(PROCES_LOG ID='.$plog->ID.')'.'</span>';
				echo'</p>';
			}
		}
	}

	echo'<div class="box box-silver">';

	$id_step_wskaznik = $plog->ID_STEP_WSKAZNIK;

	$form_zasob_id = 0;
	$wsk = ProcesHelper::get_wskazniki( $step->ID );
	$wsk_split = ProcesHelper::split_wskazniki_by_table( $wsk );

	// proces step info
	echo'<p>';
		echo'['.$step->ID.']';
		echo' <span class="red">'.$step->DESC.'</span>';
		if ($step->OPIS) echo'<br />'.$step->OPIS.'';
	echo'</p>';

	// TODO: find current

	if (empty($wsk)) {
		echo'<p>'."Nie ma nic do zrobnienia w tym kroku.".'</p>';
	} else {
		foreach ($wsk as $w) {
			if ($id_step_wskaznik == 0) {
				if ($form_zasob_id == 0) {
					$form_zasob_id = $w->ID;
				}
			} else if ($id_step_wskaznik = $w->ID) {
				$form_zasob_id = $w->ID;
			} else {
				
			}
		}
	}
	

	// if not exists print next steps
	if (!empty($wsk)) {
		DEBUG_S(4, 'wskazniki', $wsk, __FILE__, __FUNCTION__, __LINE__);

		echo'<ul style="margin:0 0 0 16px;color:green">';
		$wsk_cnt = count( $wsk );
		foreach ($wsk as $w) {
			echo'<li'.((--$wsk_cnt)? '' : ' class="last"').'>';
			echo'<p>';
			//echo ' ('.$w->SORT_PRIO.')';
			echo ' [ ';
			echo ' '.$w->ID;
			echo ' <i style="color:#111;">'.$w->CP_PYTANIE.'</i>';
			echo ' <b>'.$w->TYPE.'</b>';
			echo ' '.$w->DESC;
			echo ' ]';
			// if ($tree->get_param('editable')) echo App::link("Z-", "?function_INIT=CRM_DEL_CRM_WSKAZNIK&ID=".$w->CW_ID, array('title'=>'Edytuj', 'class'=>'btn-p5'));
			echo ' <span class="silver">'.$w->OPIS.'</span>';
			//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">';print_r($w);echo'</pre>';
			if ($show_form) $zasoby_id[ $w->TYPE ] [$w->ID]= $w->CW_ID;

			$w->_parents = TreeHelper::get_all_parents( 'CRM_LISTA_ZASOBOW', $w->PARENT_ID );
			$w_parents_out = array();
			foreach ($w->_parents as $w_p_id => $w_p) {
				$w_parents_out[] = '[<b>'.$w_p->ID.'</b> '.$w_p->TYPE.' '.$w_p->DESC.']';
			}
			echo'<br /><span style="color:#555;font-size:11px;">'.implode(' / ', $w_parents_out).'</span>';

			echo'</p>';
			echo'</li>';
		}
		echo'</ul>';

		// search for KOMORKA -> TABELA -> DATABASE_MYSQL/MSSQL BAZA_DANYH
		$need_db_tbl = array();
		$need_db_cnf = array();
		$db_types = array('DATABASE_MYSQL', 'DATABASE_MSSQL', 'BAZA_DANYCH');
		foreach ($wsk as $w) {
			if ($w->TYPE != 'KOMORKA') {
				continue;
			}
			$tbl_id = 0;
			foreach ($w->_parents as $pw) {
				if ($pw->TYPE == 'TABELA') {
					$w->_tabela = $pw->DESC;
					$tbl_id = $pw->ID;
				} else if (in_array($pw->TYPE, $db_types)) {
					$w->_db_zasob_id = $pw->ID;
					$w->_db_name = $pw->DESC;
					$need_db_cnf [$pw->ID] = array();
					$need_db_tbl [$pw->ID] [$tbl_id] [$w->ID] = $w->DESC;
				}
			}
		}
		DEBUG_S(4, 'need_db_cnf', $need_db_cnf, __FILE__, __FUNCTION__, __LINE__);
		$db_cnf = array();
		foreach ($need_db_cnf as $cnf_id => $cnf) {
			$cnf = Config::getZasobConf( $cnf_id );
			if (!$cnf) {
				echo'<p class="err">'."Brak konfiguracji dla zasobu <b>$cnf_id</b>".'</p>';
			} else {
				$db = DB::getDB( $cnf_id );
				if ($db->get_errors()) {
					echo'<p class="err">'."Wystapily bledy podczas polaczenia z baza danych (zasob $cnf_id):";
						echo '<br />'.implode('<br />', $db->get_errors());
					echo'</p>';
				} else {
					$db_cnf[$cnf_id] = $db;
				}
			}
		}
		DEBUG_S(4, 'db_cnf', $db_cnf, __FILE__, __FUNCTION__, __LINE__);

		DEBUG_S(4, 'need_db_tbl', $need_db_tbl, __FILE__, __FUNCTION__, __LINE__);
		foreach ($need_db_tbl as $k_db_id => $v_tables) {
			foreach ($v_tables as $k_tbl_id => $v_fields) {
				$sql_fields = array();
				foreach ($v_fields as $k_field_id => $v_field_name) {
					$sql_fields[] = $v_field_name;
				}
				$r_table = DB::get_by_id( 'CRM_LISTA_ZASOBOW', $k_tbl_id );
				$sql_table = $r_table->DESC;
				$db = $db_cnf[ $k_db_id ];
				if ($db) {
					$sql = "select ".implode(',', $sql_fields)."
						from `".$sql_table."`
						limit 10
					";
					$res = $db->query( $sql );
					$rows = array();
					while ($r = $db->fetch( $res )) {
						$rows[] = $r;
					}
					DEBUG_S(4, 'rows ('.count($rows).')', $rows);
				}
			}
		}
		

		DEBUG_S(4, 'wskazniki', $wsk, __FILE__, __FUNCTION__, __LINE__);
	}
	echo'</div>';//box-silver

	// next steps
	echo'<div class="box box-blue">';
	$next_steps = TreeHelper::get_childrens( 'CRM_PROCES', $step->ID );
	if (empty($next_steps)) {
		echo'<p>'."Koniec procesu".'</p>';
		// TODO: zakoncz link
	} else {
		echo'<p class="blue">'."Wybierz nastepny krok:".'</p>';
		echo'<ul style="font-family: monospace;">';
		foreach ($next_steps as $r) {
			echo'<li>';
				echo App::link("<b>[".$r->ID."]</b>", "?&task=PROCES_LOG&id_proces_log=".$plog->ID."&id_step=".$r->ID, array('ico_after_text'=>'next'));
			//echo ' '.$r->ID;
			//echo ' <b>'.$r->TYPE.'</b>';
			echo ' <b class="red">'.$r->DESC.'</b>';
			echo ' <span class="cmnt">'.$r->OPIS.'</span>';
			echo'</li>';
			//TODO: a href next
		}
		echo'</ul>';
	}
	echo'</div>';

	echo'<hr />';

	$tbl = 'CRM_PROCES';

	// show proces
	$tree = new Tree( $tbl );
	$clbk = 'tree_callback__show_item_from_'.$tbl;
	$tree->set_param('show_item_callback', $clbk);
	$tree->set_param('rozwin', (!$_SESSION['ZWIN_DRZEWO']));
	$tree->set_param('editable', false);
	$tree->set_param('show_form_at_item', $id_step);
	$tree->set_param('rozwin_proces', true);
	$tree->showSubTree( $p->ID );
}


function task_CRM_MENU() {
	$user_menu = array();
	$db = DB::getDB();
	$sql = "select p.*
		from `CRM_PROCES` as p 
		where p.`TYPE`='PROCES_INIT'; 
	";
	$res = $db->query($sql);
	while ($r = $db->fetch($res)) {
		$user_menu[$r->ID] = $r;
	}

	$tree_params = array();
	$tree_params['show_proces_opis'] = false;

	$selected_stanowiska = V::get('z', array(), $_GET, 'array');
	$menu = array();
	$stanowiska = array();
	$stanowisko_proces_map = array();
	$sql = "select
			p.`ID`
			, p.`PARENT_ID`
			, p.`TYPE`
			, p.`DESC`
			, w.`ID` as w__ID
			, z.`ID` as z__ID
			, z.`TYPE` as z__TYPE
			, z.`DESC` as z__DESC
			, z.`OPIS` as z__OPIS
		from `CRM_PROCES` as p
			left join `CRM_WSKAZNIK` as w on(w.`ID_PROCES`=p.`ID`)
			left join `CRM_LISTA_ZASOBOW` as z on(z.`ID`=w.`ID_ZASOB`)
		where
			p.`TYPE`='PROCES_INIT'
			-- TODO:?: and p.`A_STATUS` in('WAITING','NORMAL','MONITOR')
			and w.`A_STATUS` in('WAITING','NORMAL','MONITOR')
		--	and w.`ID_PRZYPADEK`=1
			and z.`TYPE`='STANOWISKO'
	";
	$res = $db->query($sql);
	while ($r = $db->fetch($res)) {
		if (!array_key_exists($r->ID, $menu)) {
			$menu[$r->ID] = $r;
			$menu[$r->ID]->KTO = array();
		}
		$z = new stdClass();
		$z->ID = $r->z__ID;
		$z->TYPE = $r->z__TYPE;
		$z->DESC = $r->z__DESC;
		$z->OPIS = $r->z__OPIS;
		$stanowiska[ $r->z__ID ] = $z;
		$stanowisko_proces_map[$z->ID][] = $r->ID;
		$menu[$r->ID]->KTO [ $r->z__ID ]= $z;
	}

	{// test
	echo'<div class="box box-green tree-wrap" style="display:none">';
	echo'<ul>';
	foreach ($menu as $k_proces_id => $v_proces) {
		echo'<li>';
		echo'<span class="btn-box btn-box-red">'.$k_proces_id.'</span>';
		echo'<b class="red">'.$v_proces->DESC.'</b>';
		echo'<ul>';
		if (empty($v_proces->KTO)) {
			echo'<li>'.'<b class="red">'."TODO: brak przypisanego stanowiska!".'</b>'.'</li>';
		} else {
			foreach ($v_proces->KTO as $k_zasob_id => $v_zasob) {
				echo '<li>'.'<span class="btn-box btn-box-green">'.$v_zasob->ID.'</span><b class="green">'.$v_zasob->DESC.'</b>'.'</li>';
			}
		}
		echo'</ul>';
		echo'</li>';
	}
	echo'</ul>';
	echo'</div>';// .box-green
	}// test

	if (empty($stanowiska)) {
		echo'<p class="box box-red red">'."Error: brak przypisanych stanowisk do procesów (PROCES_INIT)!".'</p>';
		return;
	}
	echo'<form action="" method="get">';
	echo'<p>'."Wybierz stanowiska:".'</p>';
		echo'<input type="hidden" name="task" value="'.App::get_task().'" />';
		echo'<select name="'."z[]".'" size="5" multiple="multiple" style="width:600px;">';
		foreach ($stanowiska as $k_zasob_id => $v_zasob) {
			$sel = (in_array($k_zasob_id, $selected_stanowiska))? ' selected="selected"' : '';
			echo'<option value="'.$v_zasob->ID.'"'.$sel.'>'.$v_zasob->ID.': '.$v_zasob->DESC.'</option>';
		}
		echo'</select>';
		if (!empty($selected_stanowiska)) {
			echo ' ';
			echo App::link("x", array('task'=>App::get_task()), array('ico'=>'del.png', 'title'=>"Usuń zaznaczenie"));
			echo ' ';
		}
		echo'<input type="submit" value="'."Pokaz menu".'" />';
	echo'</form>';

	$user_menu_tree_flat = array();
	if (!empty($selected_stanowiska)) {
		$show_procesy_id = array();
		foreach ($selected_stanowiska as $v_zasob_id) {
			foreach ($stanowisko_proces_map[$v_zasob_id] as $v_proces_id) {
				$show_procesy_id[$v_proces_id] = true;
			}
		}
		foreach ($show_procesy_id as $p_id => $v_bool) {
			if (array_key_exists($p_id, $menu)) {
				$user_menu_tree_flat [$menu[$p_id]->ID] = null;
				$user_menu_tree_flat [$menu[$p_id]->PARENT_ID] = null;
			}
		}
	} else {
		DEBUG_S(1,'user_menu',$user_menu, __FILE__, __FUNCTION__, __LINE__);
		foreach ($user_menu as $p_id => $p) {
			$user_menu_tree_flat [$p->ID] = null;
			$user_menu_tree_flat [$p->PARENT_ID] = null;
		}
	}


	function this_user_menu_tree_fetch_data(&$user_menu, $user_menu_tree_flat, $selected_stanowiska) {
		$db = DB::getDB();
		$sql_ids = array();
		$sql_ids = array_keys($user_menu_tree_flat);
		// add tree parent proces info
		if (!empty($sql_ids)) {
			$sql = "select * from `CRM_PROCES` as p where p.`ID` in (".implode(", ", $sql_ids)."); ";
			$res = $db->query($sql);
			while ($r = $db->fetch($res)) {
				$user_menu[$r->ID] = $r;
			}
		}
		// add data CRM_WSKAZNIK, KTO CO
		if (empty($sql_ids)) {
			return;
		}
		$sql_only_stanowiska = "";
		if (!empty($selected_stanowiska)) {
			$sql_only_stanowiska = "and z.`ID` in(" . implode(",", $selected_stanowiska) . ")";
		}
		$sql = "select
				w.`ID` as w_ID
				, w.`ID_PROCES` as w_ID_PROCES
				, z.`ID`
				, z.`TYPE`
				, z.`DESC`
			--	, z.`OPIS`
				, w.`OPIS_ZASOB` as `OPIS`
			from `CRM_WSKAZNIK` as w
				left join `CRM_LISTA_ZASOBOW` as z on(z.`ID`=w.`ID_ZASOB`)
			where
				w.`ID_PROCES` in (".implode(", ", $sql_ids).")
				and w.`A_STATUS` in('WAITING','NORMAL','MONITOR')
				and z.`TYPE`='STANOWISKO'
				" . $sql_only_stanowiska . "
		";
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			$user_menu[$r->w_ID_PROCES]->KTO[] = $r;
		}
	}

	$user_menu_tree_created = TreeHelper::build_tree_flat( 'CRM_PROCES', $user_menu_tree_flat );

	DEBUG_S(1,'user_menu_tree_flat',$user_menu_tree_flat, __FILE__, __FUNCTION__, __LINE__);

	$user_menu_tree = TreeHelper::get_tree_from_flat( $user_menu_tree_flat );
	DEBUG_S(1,'user_menu_tree',$user_menu_tree, __FILE__, __FUNCTION__, __LINE__);

	this_user_menu_tree_fetch_data($user_menu, $user_menu_tree_flat, $selected_stanowiska);
	DEBUG_S(1,'user_menu',$user_menu, __FILE__, __FUNCTION__, __LINE__);

	function this_print_user_menu_tree( $user_menu_tree, &$user_menu, $parent_id = null, $params = array() ) {
		$cls = ($parent_id === null)? ' class="user-menu-tree tree-wrap"' : '';
		if (empty($user_menu_tree)) {
			return;
		}
		echo'<ul'.$cls.'>';
		$list_total = count($user_menu_tree);
		foreach ($user_menu_tree as $k_id => $v_arr) {
			$is_last = (--$list_total)? false : true;
			$has_childrens = (empty($v_arr))? false : true;
			echo'<li '.(($is_last)? ' class="last"' : '').'>';
			if (array_key_exists($k_id, $user_menu)) {
				$p =& $user_menu[$k_id];
				$has_wsk = false;
				if ($p->TYPE == 'PROCES_INIT') {
					if (!empty($p->KTO)) {
						$has_wsk = true;
					}
				}
				echo '<dl'.(($has_childrens)? '' : ' class="has-no-children"').'>';
				echo '<dt>';
				if ($has_wsk) echo '<div class="has_wsk">';
				echo '<span class="item_id btn-box'.(($p->TYPE == 'PROCES_INIT')? ' btn-box-red' : '').'">'.$p->ID.'</span>';
				//todo do optymalizacji ze struktur
				if ($p->TYPE == 'PROCES_INIT') {
					$sql="select ID from CRM_PROCES where IF_TRUE_GOTO='".$p->ID."' ";
					$hh=DB::query($sql);
					while($rr=DB::fetch($hh)) {
						 echo App::link('&lt;'.$rr->ID.'&nbsp;', array('task'=>"PROCES_VIEW", 'id_proces'=>$rr->ID));   
					}
				}

				echo ' <span class="user-menu-'.$p->TYPE.'">'.$p->DESC.'</span> ';
				if ($p->TYPE == 'PROCES_INIT') {
					$js_onclick = "return confirm('Czy rozpoczac proces ".$p->ID."?')";
					echo App::link("Start", "?function_init=fun_PROCES_INIT&id_proces=".$k_id, array('class'=>'btn-p5', 'title'=>'Rozpocznij proces '.$k_id, 'onclick'=>$js_onclick));
					echo App::link("Przegladaj", "?task=PROCES_VIEW&id_proces=".$k_id, array('class'=>'btn-p5', 'title'=>'Przegladaj proces '.$k_id));
					echo App::link("Przegladaj (Lista)", "?task=PROCES_VIEW_LIST&id_proces=".$k_id, array('class'=>'btn-p5', 'title'=>"Przegladaj proces - widok listy {$k_id}"));
					//echo App::link_ajax("ajax", 'ajax_get_proces', array('id_proces'=>$k_id), array('class'=>'btn-p5', 'title'=>'Ajax test proces '.$k_id));
					//echo App::link("Graf", "index.php?MENU_INIT=GRAPH_VIEW_PROCES&id_proces={$k_id}", array('class'=>'btn-p5', 'title'=>"Przegladaj graf procesu {$k_id}"));
					if (true == V::get('show_proces_opis', '', $params)) {
						echo '<span class="more-desc">' . $p->OPIS . '</span>';
					}
				}
				if ($has_wsk) echo '</div>';// .has_wsk
				echo '</dt>';
				if ($has_wsk) {
					echo '<dd>';
					echo'<ul>';
					$list_kto_total = count($p->KTO);
					foreach ($p->KTO as $v_kto) {
						$is_last = (--$list_kto_total)? false : true;
						echo'<li '.(($is_last)? ' class="last"' : '').'>';
						echo '<span class="btn-box btn-box-green">'.$v_kto->ID.'</span>';
						echo ' <span class="green">'.'<b>'."$v_kto->DESC".'</b>'." $v_kto->OPIS".'</span>';
						echo'</li>';
					}
					echo'</ul>';
					echo '</dd>';
				}
				echo '</dl>';
			} else {
				echo '<dl>';
				echo '<dt>';
					echo '<span class="btn-box">'.$k_id.'</span>';
				echo '</dt>';
				echo '</dl>';
			}
			if (!empty($v_arr)) {
				this_print_user_menu_tree( $v_arr, $user_menu, $k_id, $params );
			}
			echo'</li>';
		}
		echo'</ul>';
	}

	$tree = new Tree('CRM_LISTA_ZASOBOW');
	$tree->show_css();

	echo '<p>' . "User menu:";
	//TODO: btn filter "opisy" pokaz/ukryj
	//$tree_params['show_proces_opis'] = false;
	echo '</p>';
	DEBUG_S(1,'user_menu',$user_menu, __FILE__, __FUNCTION__, __LINE__);

	if (!empty($user_menu_tree) && isset($user_menu_tree[0])) {
		this_print_user_menu_tree($user_menu_tree[0], $user_menu, null, $tree_params);
	}
}


// TODO: test
function task_CRM_MENU_NEW() {
	$user_menu = array();
	$sql = "select p.*
		from `CRM_PROCES` as p 
		where p.`TYPE`='PROCES_INIT'; 
	";
	$res = DB::query( $sql );
	while ($r = DB::fetch( $res )) {
		$r->_type = 'menu';
		$user_menu[$r->ID] = $r;
	}

	if (empty($user_menu)) {
		echo'<p>'."Brak menu".'</p>';
		return;
	}

	$selected_stanowiska = V::get('z', array(), $_GET, 'array');
	$stanowiska = array();
	$stanowisko_proces_map = array();
	$sql = "select
			p.`ID`
			, p.`PARENT_ID`
			, p.`TYPE`
			, p.`DESC`
			, w.`ID` as w__ID
			, z.`ID` as z__ID
			, z.`TYPE` as z__TYPE
			, z.`DESC` as z__DESC
			, z.`OPIS` as z__OPIS
		from `CRM_PROCES` as p
			left join `CRM_WSKAZNIK` as w on(w.`ID_PROCES`=p.`ID`)
			left join `CRM_LISTA_ZASOBOW` as z on(z.`ID`=w.`ID_ZASOB`)
		where
			p.`TYPE`='PROCES_INIT'
			and w.`A_STATUS` in('WAITING','NORMAL','MONITOR')
			and w.`ID_PRZYPADEK`=1
			and z.`TYPE`='STANOWISKO'
	";
	$res = DB::query( $sql );
	while ($r = DB::fetch( $res )) {
		if (!array_key_exists($r->ID, $user_menu)) {
			$p = new stdClass();
			$p->ID = $r->ID;
			$p->PARENT_ID = $r->PARENT_ID;
			$p->TYPE = $r->TYPE;
			$p->DESC = $r->DESC;
			$p->_type = 'menu';
			$user_menu[$r->ID] = $p;
			$user_menu[$r->ID]->KTO = array();
		}
		$z = new stdClass();
		$z->ID = $r->z__ID;
		$z->TYPE = $r->z__TYPE;
		$z->DESC = $r->z__DESC;
		$z->OPIS = $r->z__OPIS;
		$stanowiska[ $r->z__ID ] = $z;
		$stanowisko_proces_map[$z->ID][] = $r->ID;
		$user_menu[$r->ID]->KTO [ $r->z__ID ]= $z;
	}

	// show only procesy for stanowisko
	if (!empty($selected_stanowiska)) {
		$show_procesy_id = array();
		foreach ($user_menu as $k_id => $v) {
			$show_procesy_id [$k_id] = false;
		}
		foreach ($selected_stanowiska as $v_zasob_id) {
			foreach ($stanowisko_proces_map[$v_zasob_id] as $v_proces_id) {
				$show_procesy_id[$v_proces_id] = true;
			}
		}

		foreach ($show_procesy_id as $p_id => $v_bool) {
			if (array_key_exists($p_id, $user_menu)) {
				if (!$v_bool) {
					unset($user_menu[$p_id]);
				}
			}
		}
	}


	function tree_callback__show_item_from_CRM_PROCES_for_CRM_MENU( &$r, &$tree ) {
		echo'<dl>';
		if (isset($r->_type) && $r->_type == 'menu') {
			if ($r->TYPE == 'PROCES_INIT') {
				echo'<dt>';
				echo'<b class="item_id btn-box'.(($r->TYPE == 'PROCES_INIT')? ' btn-box-red' : '').'">'.$r->ID.'</b>';
				echo'<span class="desc">';
					echo'<b class="red">'.$r->DESC.'</b>';
				echo'</span>';
				echo' ';
				$js_onclick = "return confirm('Czy rozpoczac proces ".$r->ID."?')";
				echo App::link("Start", "?function_init=fun_PROCES_INIT&id_proces=".$r->ID, array('class'=>'btn-p5', 'title'=>'Rozpocznij proces '.$r->ID, 'onclick'=>$js_onclick));
				echo App::link("Przegladaj", "?task=PROCES_VIEW&id_proces=".$r->ID, array('class'=>'btn-p5', 'title'=>'Przegladaj proces '.$r->ID));
				//echo App::link_ajax("ajax", 'ajax_get_proces', array('id_proces'=>$k_id), array('class'=>'btn-p5', 'title'=>'Ajax test proces '.$k_id));
				echo'</dt>';
				if (!empty($r->KTO)) {
					echo'<dd>';
					echo'<ul>';
					$list_kto_total = count($r->KTO);
					foreach ($r->KTO as $v_kto) {
						echo'<li '.((--$list_kto_total)? '' : ' class="last"').'>';
						echo '<span class="btn-box btn-box-green">'.$v_kto->ID.'</span>';
						echo ' <span class="green">'.'<b>'."$v_kto->DESC".'</b>'." $v_kto->OPIS".'</span>';
						echo'</li>';
					}
					echo'</ul>';
					echo'</dd>';
				}
			}
		}
		else {// parent item
			echo'<dt>';
				echo'<b class="item_id btn-box">'.$r->ID.'</b>';
				echo' <span class="silver">'.$r->DESC.'</span>';
			echo'</dt>';
		}
		echo'</dl>';
	}


	DEBUG_S(1,'user_menu',$user_menu, __FILE__, __FUNCTION__, __LINE__);

	if (empty($stanowiska)) {
		echo'<p class="box box-red red">'."Error: brak przypisanych stanowisk do procesów (PROCES_INIT)!".'</p>';
		return;
	}

	echo'<form action="" method="get">';
	echo'<p>'."Wybierz stanowiska:".'</p>';
		echo'<input type="hidden" name="task" value="'.App::get_task().'" />';
		echo'<select name="'."z[]".'" size="5" multiple="multiple">';
		foreach ($stanowiska as $k_zasob_id => $v_zasob) {
			$sel = (in_array($k_zasob_id, $selected_stanowiska))? ' selected="selected"' : '';
			echo'<option value="'.$v_zasob->ID.'"'.$sel.'>'.$v_zasob->ID.': '.$v_zasob->DESC.'</option>';
		}
		echo'</select>';
		echo'<input type="submit" value="'."Pokaz menu".'" />';
	echo'</form>';

	echo'<p>'."User menu:".'</p>';

	$tbl = 'CRM_PROCES';

	$tree = new Tree( $tbl );
	$clbk = 'tree_callback__show_item_from_CRM_PROCES_for_CRM_MENU';
	$tree->set_param('show_item_callback', $clbk);
	$tree->set_param('rozwin', true);
	$tree->set_param('editable', false);
	$tree->set_param('rozwin_proces', true);
	$tree->showItems( $user_menu );
}
