<?php


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


function fun_CRM_TESTY_ADD() {
	$redirect = "?task=".App::get_task();
	$msg = '';
	App::get_msgs();
	$sql_obj = new stdClass();

	$sql_obj->ID_PROCES_INIT = V::get('proces_id', 0, $_GET, 'int');
	$sql_obj->ID_STANOWISKO = V::get('stanowisko_id', 0, $_GET, 'int');
	$sql_obj->TEST_TYPE = V::get('test_type', '', $_GET);
	$sql_obj->ID_TESTER = User::getID();

	// validate
	$has_errors = false;
	if ($sql_obj->ID_STANOWISKO <= 0) {
		App::add_error("Bledny numer stanowiska!");
		$has_errors = true;
	} else {
		$redirect .= "&stanowisko_id={$sql_obj->ID_STANOWISKO}";
	}
	if ($sql_obj->ID_PROCES_INIT <= 0) {
		App::add_error("Bledny numer procesu!");
		$has_errors = true;
	}
	if ($sql_obj->ID_STANOWISKO > 0 && $sql_obj->ID_PROCES_INIT > 0) {
		if (!ACL::canGroupViewProces($sql_obj->ID_STANOWISKO, $sql_obj->ID_PROCES_INIT)) {
			App::add_error("Grupa nie ma dostępu do procesu!");
			$has_errors = true;
		}
	}
	if (!in_array($sql_obj->TEST_TYPE, array('TEORETYCZNY', 'PRAKTYCZNY'))) {
		App::add_error("Bledny typ testu!");
		$has_errors = true;
	}

	if (!$has_errors) {
		$db = DB::getDB();
		$new_id = $db->ADD_NEW_OBJ('CRM_TESTY', $sql_obj);

		if ($new_id > 0) {
			$redirect = "?task="."CRM_TEST"."&test_id=".$new_id;// TODO: hide_menu - hide user panel
			App::add_msg("Rozpocznij test");
		}
		else {
			App::add_error("Error przy dodawaniu rekordu!");
		}
	}
	App::redirect($redirect, $msg);
}

function fun_CRM_TESTY__ADD_FIX() {
	$redirect = "?task=".App::get_task();
	$msg = '';
	$sqlObj = new stdClass();
	$hasErrors = false;

	$sqlObj->ID_TEST_TO_FIX = V::get('test_id', '', $_GET, 'int');
	if (!$sqlObj->ID_TEST_TO_FIX) {
		App::add_error("Bledny numer testu!");
		$hasErrors = true;
	}

	$db = DB::getDB();
	if (!$db) {
		App::add_error("Błąd bazy danych!");
		$hasErrors = true;
	}

	$oldTest = $db->get_by_id('CRM_TESTY', $sqlObj->ID_TEST_TO_FIX);
	if (!$oldTest) {
		App::add_error("Test do poprawy nie istnieje ({$sqlObj->ID_TEST_TO_FIX}).");
		$hasErrors = true;
	}

	$sqlObj->ID_TESTER = User::getID();
	if ($sqlObj->ID_TESTER != $oldTest->ID_TESTER) {
		App::add_error("Nie można poprawiać cudzych testów ({$sqlObj->ID_TESTER},{$oldTest->ID_TESTER}).");
		$hasErrors = true;
	}

	$sqlObj->ID_PROCES_INIT = $oldTest->ID_PROCES_INIT;
	$sqlObj->ID_STANOWISKO = $oldTest->ID_STANOWISKO;
	$sqlObj->TEST_TYPE = $oldTest->TEST_TYPE;

	if (!$hasErrors) {
		$newId = $db->ADD_NEW_OBJ('CRM_TESTY', $sqlObj);

		if ($newId > 0) {
			$sql = "insert into `CRM_TESTY_ODPOWIEDZI` (
					`ID_TEST`
					, `ID_PYTANIE`
					, `ODPOWIEDZ`
					, `ODP_0`
					, `ODP_1`
					, `ODP_2`
					, `ODP_3`
					, `ODP_4`
					, `OCENA`
				)
				select
					{$newId} as `ID_TEST`
					, q.`ID_PYTANIE`
					, q.`ODPOWIEDZ`
					, q.`ODP_0`
					, q.`ODP_1`
					, q.`ODP_2`
					, q.`ODP_3`
					, q.`ODP_4`
					, 0 as `OCENA`
				from `CRM_TESTY_ODPOWIEDZI` as q
				where `ID_TEST`={$sqlObj->ID_TEST_TO_FIX}
			";
			$db->query($sql);

			$redirect = "?task=CRM_TEST&test_id={$newId}";// TODO: hide_menu - hide user panel
			App::add_msg("Rozpocznij test");
		}
		else {
			App::add_error("Error przy dodawaniu rekordu!");
		}
	}
	App::redirect($redirect, $msg);
}

/**
 * @param $_GET['kandydat_id'] - kandydat id
 */
function fun_CRM_TESTY_RELOGIN_AS_KANDYDAT() {
	$redirect = "?task=" . "CRM_TESTY";
	$msg = '';
	$kandydat_id = V::get('kandydat_id', 0, $_POST, 'int');

	if (!User::hasAccess('procesy_admin')) {
		$msg = "Brak uprawnień do logowania Kandydatów";
	}
	else {
		session_destroy();
		session_start();

		$errors = array();
		User::kandydatLogin($kandydat_id, $errors);

		if (User::logged()) {
			// ok
		} else {
			// not ok - log in
		}
	}
	App::redirect($redirect, $msg);
}


/**
 * Add kandydat to `ADMIN_USERS`.
 * @param $_POST['f_name']
 * @param $_POST['f_tel']
 * @param $_POST['f_email']
 */
function fun_CRM_TESTY_ADD_KANDYDAT() {
	$redirect = "?task=".App::get_task();
	$msg = '';
	$sql_obj = new stdClass();

	$sql_obj->ADM_NAME = V::get('f_name', '', $_POST);
	$sql_obj->ADM_PHONE = V::get('f_tel', '', $_POST);
	$sql_obj->EMAIL = V::get('f_email', '', $_POST);
	$sql_obj->ADM_PASSWD = md5('Kandydat');
	$sql_obj->ADM_ADMIN_LEVEL = 6;
	$sql_obj->A_STATUS = 'WAITING';
	$sql_obj->ADM_ACCOUNT = 'Kandydat';
	$sql_obj->ADM_AREA = 'KANDYDAT';
	$sql_obj->ADM_ADMIN_DESC = 'Kandydat';
	$sql_obj->EMPLOYEE_TYPE = 'Kandydat';

	$error = false;
	if (!$sql_obj->ADM_NAME) {
		App::add_error("Podaj imie i nazwisko");
		$error = true;
	}
	if (!$sql_obj->ADM_PHONE) {
		App::add_error("Podaj numer telefonu");
		$error = true;
	}
	if (!$sql_obj->EMAIL) {
		App::add_error("Podaj adres e-mail");
		$error = true;
	}

	if ($error) {
		//App::redirect($redirect, $msg);
		return;
	}

	$db = DB::getDB();
	$new_id = $db->ADD_NEW_OBJ( 'ADMIN_USERS', $sql_obj );

	if ($new_id > 0) {
		App::add_msg("Dodano nowego kandydata");

		// update login name `ADM_ACCOUNT` to uniq name
		$sql_obj = new stdClass();
		$sql_obj->ID = $new_id;
		$sql_obj->ADM_ACCOUNT = 'Kandydat.'.$new_id;
		$affected = $db->UPDATE_OBJ( 'ADMIN_USERS', $sql_obj );
		if ($affected == 2) {
			App::add_msg("ok");
		} else if ($affected == 1) {
			// nie zapisano historii - ok
		} else {
			App::add_error("Error przy zmianie loginu kandydata!".$db->error());
		}
	}
	else {
		App::add_error("Error przy dodawaniu kandydata!!");
	}
	App::redirect($redirect, $msg);
}


/**
 * @param $_GET['test_id'] - ID rekordu.
 */
function fun_CRM_TEST_EDIT() {
	$test_id = V::get('test_id', 0, $_GET, 'int');
	$redirect = "?task=".App::get_task()."&test_id=".$test_id;
	$msg = '';
	$sql_obj = new stdClass();

	$test_obj = DB::get_by_id( 'CRM_TESTY', $test_id );

	$subtask = V::get('subtask', '', $_REQUEST);

	if ($subtask == 'INIT') {
		if ($test_obj->A_STATUS == 'WAITING') {
			$sql_obj->ID = $test_obj->ID;
			$sql_obj->A_STATUS = 'MONITOR';
			$sql_obj->TEST_INIT = 'NOW()';

			$affected = DB::UPDATE_OBJ( 'CRM_TESTY', $sql_obj );
			if ($affected == 2) {
				App::add_msg("Test rozpoczety");
			} else if ($affected == 1) {
				App::add_error("Zmienio rekord (Error: nie zapisano hostorii)");
			} else if ($affected < 0) {
				App::add_error("Blad podczas edytowania rekordu - nic nie zmieniono");
			}
		}
		else {
			// TODO: mozna sprawdzic aktualny status - msg
			App::add_error("Nie mozna rozpoczac testu");
		}
	}
	else if ($subtask == 'START') {
		if ($test_obj->A_STATUS == 'MONITOR') {
			$sql_obj->ID = $test_obj->ID;
			$sql_obj->A_STATUS = 'MONITOR';// start test
			$sql_obj->TEST_START = 'NOW()';

			$affected = DB::UPDATE_OBJ( 'CRM_TESTY', $sql_obj );
			if ($affected == 2) {
				App::add_msg("Uruchomiono test");
			} else if ($affected == 1) {
				App::add_error("Zmienio rekord (Error: nie zapisano hostorii)");
			} else if ($affected < 0) {
				App::add_error("Blad podczas edytowania rekordu - nic nie zmieniono");
			}
		}
		else {
			// TODO: mozna sprawdzic aktualny status - msg
			App::add_error("Nie mozna rozpoczac testu");
		}
	}
	else if ($subtask == 'SAVE') {// zapisz podane odpowiedzi
		Lib::loadClass( 'ProcesTestyHelper' );
		$odpowiedzi = ProcesTestyHelper::get_odpowiedzi( $test_obj->ID );

		$pytania_id = array();
		foreach ($odpowiedzi as $k_id_proces => $v_odp) {
			foreach ($v_odp as $k_id_pyt => $v_pyt) {
				$pytania_id[$k_id_pyt] = $v_pyt;
			}
		}

		$user_odpowiedzi = array();
		if (!empty($_POST)) {
			foreach ($_POST as $k => $v) {
				if (substr($k, 0, 4) == 'ODP_') {
					$k_id_pyt = substr($k, 4);
					if (strpos($k_id_pyt, '_ODP_') !== false) {
						$k_id_pyt_arr = explode('_ODP_', $k_id_pyt);
						if (count($k_id_pyt_arr) == 2) {
							$user_odpowiedzi[ $k_id_pyt_arr[0] ][ $k_id_pyt_arr[1] ] = $v;
						}
					} else {
						$user_odpowiedzi[ $k_id_pyt ] = $v;
					}
				}
			}
		}

		foreach ($user_odpowiedzi as $k_id_pyt => $v_odp) {
			if (array_key_exists($k_id_pyt, $pytania_id)) {
				// update odp
				$sql_obj = new stdClass();
				$sql_obj->ID = $pytania_id[$k_id_pyt]->ID;
				$sql_obj->ID_TEST = $test_obj->ID;
				$sql_obj->ID_PYTANIE = $k_id_pyt;
				$sql_obj->ODPOWIEDZ = '';
				$sql_obj->ODP_0 = '';
				$sql_obj->ODP_1 = '';
				$sql_obj->ODP_2 = '';
				$sql_obj->ODP_3 = '';
				$sql_obj->ODP_4 = '';
				$is_odp = false;
				if (is_array($v_odp)) {
					for ($i = 0; $i < 5; $i++) {
						if (isset($v_odp[$i])) {
							$is_odp = true;
							$field = "ODP_".$i;
							$sql_obj->$field = $v_odp[$i];
						}
					}
				} else {
					$is_odp = true;
					$sql_obj->ODPOWIEDZ = $v_odp;
				}

				if ($is_odp) {// pomin puste
					$affected = DB::UPDATE_OBJ( 'CRM_TESTY_ODPOWIEDZI', $sql_obj );
					if ($affected == 2) {
						App::add_msg("Zapisano odpowiedz do [".$k_id_pyt."]");
					} else if ($affected == 1) {
						App::add_error("Zapisano odpowiedz do [".$k_id_pyt."] (Error: nie zapisano hostorii)");
					} else if ($affected < 0) {
						App::add_error("Blad podczas zapisu odpowiedzi do [".$k_id_pyt."]");
					}
				}
			} else {
				// add odp
				$sql_obj = new stdClass();
				$sql_obj->ID_TEST = $test_obj->ID;
				$sql_obj->ID_PYTANIE = $k_id_pyt;
				$sql_obj->ODPOWIEDZ = '';
				$sql_obj->ODP_0 = '';
				$sql_obj->ODP_1 = '';
				$sql_obj->ODP_2 = '';
				$sql_obj->ODP_3 = '';
				$sql_obj->ODP_4 = '';
				$is_odp = false;
				if (is_array($v_odp)) {
					for ($i = 0; $i < 5; $i++) {
						if (!empty($v_odp[$i])) {
							$is_odp = true;
							$field = "ODP_".$i;
							$sql_obj->$field = $v_odp[$i];
						}
					}
				} else {
					if (!empty($v_odp)) {
						$is_odp = true;
						$sql_obj->ODPOWIEDZ = $v_odp;
					}
				}

				if ($is_odp) {
					$new_id = DB::ADD_NEW_OBJ( 'CRM_TESTY_ODPOWIEDZI', $sql_obj );
					if ($new_id > 0) {
						App::add_msg("Zapisano odpowiedz do [".$k_id_pyt."]");
					} else {
						App::add_error("Blad podczas zapisu odpowiedzi do [".$k_id_pyt."]");
					}
				}
			}
		}

		// zakoncz test
		if (!empty($_POST['save_and_end']) && $test_obj->A_STATUS == 'MONITOR') {
			$sql_obj = new stdClass();
			$sql_obj->ID = $test_obj->ID;
			$sql_obj->A_STATUS = 'NORMAL';// start test
			$sql_obj->TEST_END = 'NOW()';

			$affected = DB::UPDATE_OBJ( 'CRM_TESTY', $sql_obj );
			if ($affected == 2) {
				App::add_msg("Zakonczono test");
			} else if ($affected == 1) {
				App::add_error("Zmienio rekord (Error: nie zapisano hostorii)");
			} else if ($affected < 0) {
				App::add_error("Blad podczas edytowania rekordu - nic nie zmieniono");
			}
		}
	}
	else if ($subtask == 'OCEN') {// zapisz ocen
		$kandydat_id = V::get('kandydat_id', 0, $_GET, 'int');
		$redirect .= "&kandydat_id=".$kandydat_id;

		if ($test_obj->A_STATUS == 'NORMAL' || $test_obj->A_STATUS == 'OFF_HARD') {
			$oceny = array();// zazanczone oceny ($_POST)
			$oceny_id = array();// [ID_PYT] = {ID,ID_PYTANIE,ID_PROCES,ODPOWIEDZ,ODP_0/1/2/3/4,OCENA}
			$oceny_empty = array();// zazanczone oceny ($_POST), ale brak rekordow w tabeli odpowiedzi - user not answer
			$pytania_empty = array();// j/w
			$avg_odpowiedzi_pyt = array();// wszystkie odpowiedzi [ID_PROCES][ID_PYT] = OCENA
			Lib::loadClass('ProcesTestyHelper');
			$odpowiedzi = ProcesTestyHelper::get_odpowiedzi($test_obj->ID);

			$pytania_id = array();
			foreach ($odpowiedzi as $k_id_proces => $v_odp) {
				foreach ($v_odp as $k_id_pyt => $v_pyt) {
					$oceny_id[$k_id_pyt] = $v_pyt;
				}
			}

			// zaznaczone oceny
			if (!empty($_POST)) {
				$req_prefix = 'ocena_';
				foreach ($_POST as $k => $v) {
					if (substr($k, 0, strlen($req_prefix)) == $req_prefix) {
						$id_pyt = substr($k, strlen($req_prefix));
						$oceny[$id_pyt] = $v;
						if (!array_key_exists($id_pyt, $oceny_id)) {
							$oceny_empty[$id_pyt] = true;
						}
					}
				}
			}

			// dla kazdego procesu obliczyc srednia na podstawie ocen odpowiedzi na pytania
			if (!empty($oceny_empty)) {
				$pytania_empty = ProcesTestyHelper::get_pytania_by_id(array_keys($oceny_empty));
			}

			foreach ($oceny as $k_id_pyt => $v_odp) {
				if (array_key_exists($k_id_pyt, $oceny_id)) {
					// update odp
					$odp_row = $oceny_id[$k_id_pyt];
					$sql_obj = new stdClass();
					$sql_obj->ID = $odp_row->ID;
					$sql_obj->OCENA = $oceny[$k_id_pyt];
					$avg_odpowiedzi_pyt[$odp_row->ID_PROCES][$odp_row->ID_PYTANIE] = $oceny[$k_id_pyt];

					$affected = DB::UPDATE_OBJ( 'CRM_TESTY_ODPOWIEDZI', $sql_obj );
					if ($affected == 2) {
						App::add_msg("Zapisano ocene do [".$k_id_pyt."]");
					} else if ($affected == 1) {
						App::add_error("Zapisano ocene do [".$k_id_pyt."] (Error: nie zapisano hostorii)");
					} else if ($affected < 0) {
						App::add_error("Blad podczas zapisu oceny do [".$k_id_pyt."]");
					}
				}
				else if (array_key_exists($k_id_pyt, $pytania_empty)) {
					// error odpowiedz not exists, add OCENA = 0 - nic
					$pyt_row = $pytania_empty[$k_id_pyt];
					$avg_odpowiedzi_pyt[$pyt_row->ID_PROCES][$pyt_row->ID] = $oceny[$k_id_pyt];
				}
				else {
					// TODO: error unknown!
				}
			}

			$ocena_avg = 0;
			// oblicz srednia dla kazdego procesu
			if (!empty($avg_odpowiedzi_pyt)) {
				$avg_odpowiedzi = array();// wszystkie odpowiedzi [ID_PROCES] = OCENA (avg from $avg_odpowiedzi_pyt[ID_PROCES])
				$avg_max = 0;
				$avg_sum = 0;
				//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">avg_odpowiedzi_pyt: ';print_r($avg_odpowiedzi_pyt);echo'</pre>';
				foreach ($avg_odpowiedzi_pyt as $k_id_proces => $v_odp) {
					if ('' != $v_odp) {
						$p_avg_sum = 0;
						foreach ($v_odp as $k_id_pyt => $v_ocena) {
							$p_avg_sum += $v_ocena;
						}
						$p_avg_max = count($v_odp);// max 3 za pytanie
						$p_avg = floatval($p_avg_sum) / $p_avg_max;// srednia procesu $k_id_proces
						$avg_odpowiedzi[$k_id_proces] = $p_avg;
						$avg_sum += $p_avg;
					}
				}

				if (!empty($avg_odpowiedzi)) {
					$avg_max = count($avg_odpowiedzi);
					$ocena_avg = round($avg_sum / $avg_max, 2);
					//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">avg_odpowiedzi: ';print_r($avg_odpowiedzi);echo'</pre>';
					//echo'{AVG: '.$avg_sum.'/'.$avg_max.' = '.($avg_sum / $avg_max).' ~ '.$ocena_avg.'}';
				}
			}

			if (empty($avg_odpowiedzi_pyt) && $ocena_avg == 0) {
				$ocena_avg = -1;// Brak pytań
			}

			$sql_obj = new stdClass();
			$sql_obj->ID = $test_obj->ID;
			$sql_obj->A_STATUS = 'OFF_HARD';// test oceniony
			$sql_obj->UWAGI = V::get('f_uwagi', '', $_POST);
			$sql_obj->OCENA = $ocena_avg;

			$affected = DB::UPDATE_OBJ( 'CRM_TESTY', $sql_obj );
			if ($affected == 2) {
				App::add_msg("Oceniono test: $ocena_avg/3");
			} else if ($affected == 1) {
				App::add_error("Oceniono test (Error: nie zapisano hostorii)");
			} else if ($affected < 0) {
				App::add_error("Blad podczas oceniania testu - nic nie zmieniono");
			}
		}
	}
	else if ($subtask == 'EDIT') {// zapisz dane
		if ($test_obj->A_STATUS == 'OFF_HARD') {
			$sql_obj->ID = $test_obj->ID;
			$sql_obj->UWAGI = V::get('UWAGI', '', $_POST);
			$sql_obj->COST = V::get('COST', 0, $_POST, 'double');
			$sql_obj->DISCOUNT = V::get('DISCOUNT', 0, $_POST, 'double');
			$sql_obj->ID_ORGANIZER = V::get('ID_ORGANIZER', 0, $_POST, 'int');
			$sql_obj->TEST_PLACE = V::get('TEST_PLACE', '', $_POST);
			$sql_obj->SHOW_IN_CERT = V::get('SHOW_IN_CERT', '', $_POST);
			$affected = DB::UPDATE_OBJ( 'CRM_TESTY', $sql_obj );
			if ($affected == 2) {
				App::add_msg("Zapisano zmiany");
			} else if ($affected == 1) {
				App::add_error("Zmienio rekord (Error: nie zapisano hostorii)");
			} else if ($affected < 0) {
				App::add_error("Blad podczas edytowania rekordu - nic nie zmieniono");
			}
		}
	}
	else {
		App::add_error("Wrong task");
	}

	App::redirect($redirect, $msg);
}


/**
 * @param $_GET['test_id'] - ID z tabeli CRM_TESTY
 */
function task_CRM_TEST() {
	$test_id = V::get('test_id', 0, $_GET, 'int');

	Lib::loadClass('ProcesTestyHelper');

	if ($test_id <= 0) {
		echo'<p class="err">'."Wrong ID".'</p>';
		return;
	}

	$test_obj = DB::getPDO()->fetchFirstAsObject(" select * from CRM_TESTY where ID = :ID ", [ 'ID' => $test_id ]);
	if (!$test_obj) {
		echo'<p class="red">'."Wrond ID.".'</p>';
		return;
	}

	$stanowisko = DB::getPDO()->fetchFirstAsObject(" select * from CRM_LISTA_ZASOBOW where ID = :ID ", [ 'ID' => $test_obj->ID_STANOWISKO ]);
	$proces = DB::getPDO()->fetchFirstAsObject(" select * from CRM_PROCES where ID = :ID ", [ 'ID' => $test_obj->ID_PROCES_INIT ]);

	if (!$proces || !$stanowisko) {
		UI::alert('danger', "Błędny proces lub stanowisko!");
		return;
	}
	echo UI::h('div', [ 'class' => "container" ], [
		UI::h('div', [ 'class' => "panel panel-default" ], [
			UI::h('div', [ 'class' => "panel-heading" ], "Test:"),
			UI::h('div', [ 'class' => "panel-body" ], [
				UI::h('ul', [], [
					UI::h('li', [], [
						"Proces: ",
						UI::h('b', [ 'class' => "text-danger" ], "{{$proces->ID}} {$proces->DESC}"),
					]),
					UI::h('li', [], [
						"Stanowisko: ",
						UI::h('b', [ 'class' => "text-success" ], "[{$stanowisko->ID}] {$stanowisko->DESC}"),
					]),
				]),
			]),
		]),
	]);

	$lastTestDate = null;
	if ($test_obj->ID_TEST_TO_FIX > 0) {
		$testToFix = DB::get_by_id('CRM_TESTY', $test_obj->ID_TEST_TO_FIX);
		$lastTestDate = $testToFix->TEST_END;
		if ($lastTestDate == '0000-00-00 00:00:00') $lastTestDate = $testToFix->TEST_START;
		if ($lastTestDate == '0000-00-00 00:00:00') $lastTestDate = $testToFix->TEST_INIT;
		if ($lastTestDate == '0000-00-00 00:00:00') $lastTestDate = null;
	}

/*
 * WAITING - nowy test - oczekiwanie na rozpoczecie testu
 * MONITOR - test rozpoczety z data TEST_INIT
 * NORMAL - test zakonczony - do ocenienia TEST_END
 * OFF_HARD - test oceniony
 */
	if ($test_obj->A_STATUS == 'WAITING') {// nowy test - oczekiwanie na rozpoczecie testu
		echo App::link("Rozpocznij", array('task'=>App::get_task(), 'function_init'=>'fun_CRM_TEST_EDIT', 'subtask'=>'INIT', 'test_id'=>$test_obj->ID), array('class'=>'btn btn-primary'));
	}
	else if ($test_obj->A_STATUS == 'MONITOR' && $test_obj->TEST_START == '0000-00-00 00:00:00') {// czytanie - test rozpoczety z data TEST_INIT
		$id_proces = $test_obj->ID_PROCES_INIT;

		$p = DB::getPDO()->fetchFirstAsObject(" select * from CRM_PROCES where ID = :ID ", [ 'ID' => $id_proces ]);
		if (!$p) {
			echo '<div class="alert alert-danger">' . "Proces {$id_proces} nie istnieje" . '</div>';
			return;
		}

		Lib::loadClass('TreeListView');
		$treeList = new TreeListView('CRM_PROCES', $id_proces, 'PARENT_ID');
		$treeList->fetchTreeFlat();
		$listFlat = $treeList->generateListFlat();
		$treeList->fetchData();

		$ids = $treeList->getListIds();
		$wskazniki = ProcesHelper::getWskaznikiByIds($ids, array('group_stanowiska' => 1));
		if(V::get('DBG_TF', '', $_GET) > 1){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$wskazniki (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($wskazniki);echo'</pre>';}

		$gotoLinks = array();
		$gotoIds = array();
		foreach ($listFlat as $vItem) {
			$item = $treeList->getData($vItem->ID);
			if ($item->IF_TRUE_GOTO > 0) {
				$gotoIds[] = $item->IF_TRUE_GOTO;
			}
		}
		if (!empty($gotoIds)) {
			$sqlIds = implode(",", $gotoIds);
			$sql = "
				select p.`ID`, p.`DESC`
					-- , p.`OPIS`
				from `CRM_PROCES` as p
				where
					p.`A_STATUS` in('WAITING', 'NORMAL')
					and p.`ID` in({$sqlIds})
			";
			$gotoLinks = array_map(function ($row) {
				return $row['DESC'];
			}, DB::getPDO()->fetchAllByKey($sql, 'ID'));
		}

		foreach ($listFlat as $vItem) {
			$item = $treeList->getData($vItem->ID);
			$itemDate = ($item->A_RECORD_UPDATE_DATE)? $item->A_RECORD_UPDATE_DATE : $item->A_RECORD_CREATE_DATE;
			if ($itemDate > $lastTestDate) {
				$vItem->changedAfterLastTest = true;
			}

			if(V::get('DBG_TF', '', $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">wskazniki['.$item->ID.'] (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($wskazniki[$item->ID]);echo'</pre>';}

			$vItem->gotoOut = '';
			if ($item->IF_TRUE_GOTO > 0) {
				$gotoLink = "{{$item->IF_TRUE_GOTO}}";
				if (!V::get('HIDE_PANEL', 0, $_GET, 'int')) {
					$gotoLink = App::link($gotoLink, array('task'=>'PROCES_VIEW_LIST', 'id_proces'=>$item->IF_TRUE_GOTO));
				}
				if ($item->IF_TRUE_GOTO_FLAG == 'GOTO') {
					$vItem->gotoOut .= "Przejdź do procesu {$gotoLink}";
				} else if ($item->IF_TRUE_GOTO_FLAG == 'GOTO_AND_RETURN') {
					$vItem->gotoOut .= "Przejdź do procesu {$gotoLink} i wróć po jego zakończeniu";
				} else if ($item->IF_TRUE_GOTO_FLAG == 'FORK') {
					$vItem->gotoOut .= "Uruchom propces {$gotoLink}";
				}
				if (!empty($vItem->gotoOut) && !empty($gotoLinks[$item->IF_TRUE_GOTO])) {
					$vItem->gotoOut .= ": {$gotoLinks[$item->IF_TRUE_GOTO]}";
				}
				$vItem->gotoOut .= ".";
			}
		}

		$imgSize = (V::get('show_big_img', '', $_GET))? '600x600' : '200x200';

		?>
		<style type="text/css">
.proces-list-view-image { float:right; padding:0 0 8px 8px; clear:right; }
.changed-after-last-test { padding-left:10px; border-left:4px solid orange; }
		</style>
		<div class="container">
		<?php foreach ($listFlat as $vItem) {
			$item = $treeList->getData($vItem->ID);
			?>
			<div class="proces-list-item-view<?php if ($vItem->changedAfterLastTest) { echo ' changed-after-last-test'; } ; ?>">
				<h4>
					<?php if ($vItem->changedAfterLastTest) : ?>
						<i class="glyphicon glyphicon-exclamation-sign" style="color:orange;" title="Proces został zmieniony od poprzedniego wykonania testu"></i>
					<?php endif; ?>
					<?php echo $vItem->listNr; ?>.
					<?php echo $item->DESC; ?> <span class="muted">{<?php echo $item->ID; ?>}</span>
				</h4>
				<p style="overflow:hidden">
					<?php if ($item->A_HAS_IMAGE > 0) : ?>
						<?php $tbl = 'CRM_PROCES'; ?>
						<?php for ($i = 0; $i < $item->A_HAS_IMAGE; $i++) : ?>
							<a href="procesy5.php?function_init=fun_SHOW_EXTERNAL_IMAGE&tbl=<?php echo $tbl; ?>&id=<?php echo $item->ID; ?>&number=<?php echo $i; ?>" target="_blank" class="proces-list-view-image lightbox">
								<img src="procesy5.php?function_init=fun_SHOW_EXTERNAL_IMAGE&tbl=<?php echo $tbl; ?>&id=<?php echo $item->ID; ?>&number=<?php echo $i; ?>&resize=<?php echo $imgSize; ?>" />
							</a>
						<?php endfor; ?>
					<?php endif; ?>
					<?php echo $item->OPIS; ?>
				</p>
				<?php if (array_key_exists($item->ID, $wskazniki)) : ?>
					<dl class="dl-horizontal">
					<?php if (!empty($wskazniki[$item->ID]['stanowiska'])) : ?>
						<dt>Stanowiska:</dt>
						<dd>
							<ul>
								<?php foreach ($wskazniki[$item->ID]['stanowiska'] as $vWsk) : ?>
									<li>
										<?php echo $vWsk->DESC; ?> <span class="muted">[<?php echo $vWsk->ID; ?>]</span>
									</li>
								<?php endforeach; ?>
							</ul>
						</dd>
					<?php endif; ?>

					<?php if (!empty($wskazniki[$item->ID]['inne'])) : ?>
						<dt>Użyte zasoby:</dt>
						<dd>
							<ul>
							<?php foreach ($wskazniki[$item->ID]['inne'] as $vWsk) : ?>
								<li style="clear:both;">
									<?php if ($vWsk->A_HAS_IMAGE > 0) : ?>
										<?php $tbl = 'CRM_LISTA_ZASOBOW'; ?>
										<?php for ($i = 0; $i < $vWsk->A_HAS_IMAGE; $i++) : ?>
											<a href="procesy5.php?function_init=fun_SHOW_EXTERNAL_IMAGE&tbl=<?php echo $tbl; ?>&id=<?php echo $vWsk->ID; ?>&number=<?php echo $i; ?>" target="_blank" class="proces-list-view-image lightbox">
												<img src="procesy5.php?function_init=fun_SHOW_EXTERNAL_IMAGE&tbl=<?php echo $tbl; ?>&id=<?php echo $vWsk->ID; ?>&number=<?php echo $i; ?>&resize=<?php echo $imgSize; ?>" />
											</a>
										<?php endfor; ?>
									<?php endif; ?>
									<?php if ($vWsk->CW_A_HAS_IMAGE > 0) : ?>
										<?php $tbl = 'CRM_WSKAZNIK'; ?>
										<?php for ($i = 0; $i < $vWsk->CW_A_HAS_IMAGE; $i++) : ?>
											<a href="procesy5.php?function_init=fun_SHOW_EXTERNAL_IMAGE&tbl=<?php echo $tbl; ?>&id=<?php echo $vWsk->CW_ID; ?>&number=<?php echo $i; ?>" target="_blank" class="proces-list-view-image lightbox">
												<img src="procesy5.php?function_init=fun_SHOW_EXTERNAL_IMAGE&tbl=<?php echo $tbl; ?>&id=<?php echo $vWsk->CW_ID; ?>&number=<?php echo $i; ?>&resize=<?php echo $imgSize; ?>" />
											</a>
										<?php endfor; ?>
									<?php endif; ?>

									<strong><?php echo (!empty($vWsk->DESC_PL))? $vWsk->DESC_PL : $vWsk->DESC; ?></strong>
									<?php echo (!empty($vWsk->OPIS))? " <em>({$vWsk->OPIS})</em>." : ''; ?>
									<?php echo (!empty($vWsk->OPIS_ZASOB))? "<br>{$vWsk->OPIS_ZASOB}" : ''; ?>
									<span class="muted">[<?php echo $vWsk->ID; ?>]</span>
								</li>
							<?php endforeach; ?>
							</ul>
						</dd>
					<?php endif; ?>
					</dl>
				<?php endif; ?>

				<?php if ($vItem->gotoOut) : ?>
					<blockquote>
						<small>
							<?php echo $vItem->gotoOut; ?>
						</small>
					</blockquote>
				<?php endif; ?>
			</div>
			<?php
		}
		echo '</div>';// .container

		?>
		<br>
		<div class="container">
			<div class="well">
				<p>
					<?php echo App::link("Przeczytalem - rozpocznij test", array('task'=>App::get_task(), 'function_init'=>'fun_CRM_TEST_EDIT', 'subtask'=>'START', 'test_id'=>$test_obj->ID), array('class'=>'btn btn-primary')); ?>
				</p>
				<p>Po rozpoczęciu testu nie ma możliwości powrotu do procesu.
				<br>Test wielokrotnego wyboru,
				należy odpowiedzieć na <b>wszystkie pytania</b> zaznaczając TAK lub NIE</p>
			</div>
		</div>
		<?php
	}
	else if ($test_obj->A_STATUS == 'MONITOR' && $test_obj->TEST_START != '0000-00-00 00:00:00') {// wype??nianie - test rozpoczety z data TEST_INIT
		$tbl = 'CRM_PROCES';
		if ($test_obj->TEST_START == '0000-00-00 00:00:00') {
			$clbk = 'tree_callback__show_item_from_'.$tbl;
		} else {
			$clbk = 'tree_callback__show_test_item_from_'.$tbl;
		}

		$tree_params = array();
		$tree_params['rozwin'] = true;
		$tree_params['editable'] = false;
		$tree_params['rozwin_proces'] = true;
		$tree_params['filtr_img'] = true;
		$tree_params['rozwin_zasoby'] = true;
		$tree_params['rozwin_opis'] = true;
		$tree_params['style'] = 'NOWY';
		$tree_params['TEST_TYPE'] = $test_obj->TEST_TYPE;
		if ($lastTestDate) $tree_params['lastTestDate'] = $lastTestDate;

		$odpowiedzi = ProcesTestyHelper::get_odpowiedzi($test_obj->ID, $test_obj->TEST_TYPE);
		foreach ($odpowiedzi as $k_id_proces => $v_odp) {
			foreach ($v_odp as $k_id_pyt => $v_pyt) {
				$tree_params["ODP_{$k_id_pyt}"] = $v_pyt->ODPOWIEDZ;
				for ($i = 0; $i < 5; $i++) {
					$v_pyt_field = "ODP_{$i}";
					$tree_params["ODP_{$k_id_pyt}_ODP_{$i}"] = $v_pyt->$v_pyt_field;
				}
				$tree_params["ocena_{$k_id_pyt}"] = $v_pyt->OCENA;
			}
		}

		if (!empty($_POST)) {
			foreach ($_POST as $k => $v) {
				if (substr($k, 0, 4) == 'ODP_') {
					$tree_params[$k] = $v;// overwrite in tree params
				}
			}
		}

		if ($test_obj->TEST_START != '0000-00-00 00:00:00') {
			echo'<form action="" method="post" class="form-inline">';
			echo'<input type="hidden" name="function_init" value="'."fun_CRM_TEST_EDIT".'" />';
			echo'<input type="hidden" name="subtask" value="'."SAVE".'" />';
		}

		action_VIEW_SUBTREE($tbl, $test_obj->ID_PROCES_INIT, $clbk, $tree_params);

		echo'<p>';
		if ($test_obj->TEST_START == '0000-00-00 00:00:00') {
			echo "Przeczytalem - ";
			echo App::link("rozpocznij test", array('task'=>App::get_task(), 'function_init'=>'fun_CRM_TEST_EDIT', 'subtask'=>'START', 'test_id'=>$test_obj->ID), array('class'=>'btn-p5'));
		} else {
			echo "";
			echo'<input class="btn btn-default" type="submit" name="save" value="'."Zapisz".'" />';
			echo' lub ';
			echo'<input class="btn btn-primary" type="submit" name="save_and_end" value="'."Zapisz i zakoncz".'" />';
		}
		echo'</p>';

		if ($test_obj->TEST_START != '0000-00-00 00:00:00') {
			echo'</form>';
		}
	}
	else if ($test_obj->A_STATUS == 'NORMAL') {// test zakonczony - do ocenienia TEST_END
		echo '<p>' . "Test uruchomiono: " . $test_obj->TEST_INIT . '</p>';
		echo '<p>' . "Test rozpoczeto: " . $test_obj->TEST_START . '</p>';
		echo '<p>' . "Test zakonczono: " . $test_obj->TEST_END . '</p>';
		echo '<br />';
		echo '<p>' . App::link("Rozpocznij nowy test", array('task'=>'CRM_TESTY__ADD_TEST'), array('class'=>'btn btn-primary')) . '</p>';
	}
	else if ($test_obj->A_STATUS == 'OFF_HARD') {// test oceniony
		echo '<p>' . "Test oceniony na " . $test_obj->OCENA . '</p>';
	}

	// $item_id isset
	// TODO: check if exists in db
	// TODO: run test - show ajax clock - prevent logout
}


function task_CRM_TESTY__LIST() {
	if (!User::hasAccess('testy')) {
		User_procesy5_check_access();
	}
	Lib::loadClass('ProcesTestyHelper');

		?>
<ol class="breadcrumb">
  <li><?php echo App::link("Testy", array('task'=>'CRM_TESTY')); ?></li>
  <li><?php echo App::link("Twoje testy", array('task'=>'CRM_TESTY__LIST')); ?></li>
</ol>
<?php

	// aktualne testy pracownika/kandydata
	$params = array();
	$params['limit'] = V::get('_limit', 20, $_GET, 'int');
	$params['offset'] = V::get('_offset', 0, $_GET, 'int');
	$params['order_by'] = V::get('_order_by', 'ID', $_GET);
	$params['order_dir'] = V::get('_order_dir', 'DESC', $_GET);
	$params['id_tester'] = User::getID();

	// validate params
	if ($params['offset'] < 0) $params['offset'] = 0;

	$lista_cnt = ProcesTestyHelper::get_testy_total($params);
	if ($lista_cnt <= 0) {
		echo '<div class="alert alert-info">' . "Brak testów." . '</div>';
		return;
	}
	if ($params['offset'] > $lista_cnt) $params['offset'] = $lista_cnt - ($lista_cnt % $params['limit']);

	echo '<style type="text/css">' . "
.cell-test_type-teoretyczny {background-color:#FFCA9B;}
.cell-test_type-praktyczny {background-color:#B3EBFB;}
	" . '</style>';

	$testy_arr = ProcesTestyHelper::get_testy($params);
	$cols = array();
	$cols['ID'] = "Nr";
	$cols['ID_TEST_TO_FIX'] = "Nr poprawianego testu";
	$cols['ID_PROCES_INIT'] = "Proces ID";
	$cols['Stanowisko'] = "Stanowisko";
	$cols['TEST_TYPE'] = "Rodzaj testu";
	$cols['TEST_INIT'] = "Rozpoczeto czytanie";
	$cols['TEST_START'] = "Rozpoczeto odpowiadanie";
	$cols['TEST_END'] = "Zakonczono";
?>
	<table class="table table-bordered table-hover">
		<thead>
			<tr>
				<?php foreach ($cols as $kFieldName => $vLabel) : ?>
					<th><?php echo $vLabel; ?></th>
				<?php endforeach; ?>
				<th></th>
			</tr>
		</thead>
		<tfoot>
			<td colspan="<?php echo count($cols) + 1; ?>">
			<?php
				$page_nav = new stdClass();
				$page_nav->total = $lista_cnt;
				$page_nav->limit = $params['limit'];
				$page_nav->current = $params['offset'];
				$page_nav->offset_start = 0;
				$page_nav->offset_prev = $page_nav->current - $page_nav->limit;
				$page_nav->offset_next = $page_nav->current + $page_nav->limit;
				$page_nav->offset_end = floor($lista_cnt / $page_nav->limit) * $page_nav->limit;
				$link_params = array('task'=>App::get_task(), '_offset'=>$page_nav->offset_start);
				if ($kandydat_id > 0) $link_params['kandydat_id'] = $kandydat_id;
				echo App::link("&lt;&lt;", $link_params, array('class'=>'btn btn-xs btn-default'));
				$link_params = array('task'=>App::get_task(), '_offset'=>$page_nav->offset_prev);
				if ($kandydat_id > 0) $link_params['kandydat_id'] = $kandydat_id;
				echo ' ' . App::link("&lt; -".$page_nav->limit, $link_params, array('class'=>'btn btn-xs btn-default'));
				echo ' <span class="btn">' . $page_nav->current.' ('.$page_nav->total.')</span> ';
				$link_params = array('task'=>App::get_task(), '_offset'=>$page_nav->offset_next);
				if ($kandydat_id > 0) $link_params['kandydat_id'] = $kandydat_id;
				echo ' ' . App::link("+".$page_nav->limit." &gt;", $link_params, array('class'=>'btn btn-xs btn-default'));
				$link_params = array('task'=>App::get_task(), '_offset'=>$page_nav->offset_end);
				if ($kandydat_id > 0) $link_params['kandydat_id'] = $kandydat_id;
				echo ' ' . App::link("&gt;&gt;", $link_params, array('class'=>'btn btn-xs btn-default'));
			?>
			</td>
		</tfoot>
		<tbody>
			<?php foreach ($testy_arr as $r) : ?>
			<tr>
				<?php foreach ($cols as $kFieldName => $vLabel) : ?>
					<td class="<?php echo ($kFieldName == 'TEST_TYPE')? 'cell-' . strtolower($kFieldName) . '-' . strtolower($r->{$kFieldName}) : ''; ?>">
						<?php echo $r->{$kFieldName}; ?>
					</td>
				<?php endforeach; ?>
				<td>
					<?php
						if ($r->A_STATUS == 'WAITING') {
							echo App::link("rozpocznij", array('task'=>'CRM_TEST', 'function_init'=>'fun_CRM_TEST_EDIT', 'subtask'=>'INIT', 'test_id'=>$r->ID), array('class'=>'btn btn-xs btn-primary'));
						} else if ($r->A_STATUS == 'MONITOR') {
							if ($r->TEST_INIT == '0000-00-00 00:00:00') {
								echo App::link("rozpocznij", array('task'=>'CRM_TEST', 'function_init'=>'fun_CRM_TEST_EDIT', 'subtask'=>'INIT', 'test_id'=>$r->ID), array('class'=>'btn btn-xs btn-primary'));
							} else {
								echo ' ' . App::link("test", array('task'=>'CRM_TEST', 'test_id'=>$r->ID), array('class'=>'btn btn-xs btn-primary'));
							}
						} else if ($r->A_STATUS == 'NORMAL') {
							echo 'Test zakonczono';
						} else if ($r->A_STATUS == 'OFF_HARD') {
							// test oceniony
						} else {
							//echo '{'.$r->A_STATUS.'}';
						}
					?>
				</td>
			</tr>
			<?php endforeach; ?>
		</tbody>
	</table>
<?php
}


function task_CRM_TESTY__ADD_KANDYDAT() {
	Lib::loadClass('ProcesTestyHelper');

	?>
<ol class="breadcrumb">
  <li><?php echo App::link("Testy", array('task'=>'CRM_TESTY')); ?></li>
  <li><?php echo App::link("Dodaj Kandydata i zaloguj się do testów", array('task'=>'CRM_TESTY__ADD_KANDYDAT')); ?></li>
</ol>
<?php

	if (!User::hasAccess('procesy')) {
		echo '<p>' . "Brak uprawnień!" . '</p>';
		return;
	}

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

	// choose kandydat
	$params = array();
	$params ['order by'] = "ADM_NAME";
	$kandydaci = ProcesTestyHelper::get_kandydaci( $params );
	if (!empty($kandydaci)) {
		$js = "return stopTimer();";
		echo '<form action="" method="post" onsubmit="' . $js . '">';
			echo '<h3>' . "Wybierz kandydata i zaloguj sie do testow: " . '</h3>';
			echo '<input type="hidden" name="function_init" value="fun_CRM_TESTY_RELOGIN_AS_KANDYDAT" />';
			$kandydaci_cnt = count($kandydaci);
			$sel_size = ($kandydaci_cnt < 10)? $kandydaci_cnt : 10;
			echo '<select name="kandydat_id" size="' . $sel_size . '">';
				echo '<option value="">' . " [ Wybierz ] " . '</option>';
			foreach ($kandydaci as $r) {
				echo '<option value="' . $r->ID . '">' . "" . $r->ADM_NAME . " [" . $r->ID . "] (" . $r->ADM_PHONE . ", " . $r->ADM_OTHER_INFO . ")" . '</option>';
			}
			echo '</select>';
			echo '<br />';
			echo '<input type="submit" value="' . "Zaloguj kandydata do testow" . '" />';
		echo '</form>';
		echo '<hr />';
	}

	// add new kandydat
	echo '<form action="" method="post">';
		echo '<h3>' . "Dodaj nowego kandydata:" . '</h3>';
		echo '<input type="hidden" name="function_init" value="' . "fun_CRM_TESTY_ADD_KANDYDAT" . '" />';
		echo '<p>';
			echo "Imie i nazwisko: ";
			echo '<input type="text" name="f_name" value="' . V::get('f_name', '', $_POST) . '" class="i" size="50" />';
		echo '</p>';
		echo '<p>';
			echo "Nr telefonu: ";
			echo '<input type="text" name="f_tel" value="' . V::get('f_tel', '', $_POST) . '" class="i" size="16" />';
		echo '</p>';
		echo '<p>';
			echo "Adres e-mail: ";
			echo '<input type="text" name="f_email" value="' . V::get('f_email', '', $_POST) . '" class="i" size="50" />';
		echo '</p>';
		echo '<input type="submit" name="save_form" value="' . "Dodaj kandydata" . '" />';
	echo '</form>';
	echo '</div>';// .box-blue
}


/**
 * $_GET['stanowisko_id']
 */
function task_CRM_TESTY__ADD_TEST() {
	$idStanowiska = V::get('stanowisko_id', 0, $_GET, 'int');
	$idProces = V::get('proces_id', 0, $_GET, 'int');
	$testType = V::get('test_type', '', $_GET);

	$linkPrint = 'procesy5.php?task=CRM_TESTY__ADD_TEST&_print=1&HIDE_PANEL=1';
	if ($idStanowiska) $linkPrint .= "&stanowisko_id={$idStanowiska}";
	// if ($idProces) $linkPrint .= "&proces_id={$idProces}";
	if ('1' != V::get('_print', '', $_GET)) {
?>
<ol class="breadcrumb">
  <li><?php echo App::link("Testy", array('task'=>'CRM_TESTY')); ?></li>
  <li><?php echo App::link("Uruchom nowy test", array('task'=>'CRM_TESTY__ADD_TEST')); ?></li>
	<?php if ($idStanowiska > 0) : ?>
		<li class="active">Testy dla stanowiska [<?php echo $idStanowiska; ?>]</li>
	<?php endif; ?>
	<a style="float:right; font-size:12px; line-height:1.5"
		target="_blank"
		href="<?= $linkPrint; ?>"><i class="glyphicon glyphicon-print"></i> drukuj</a>
</ol>
<?php
	}

	function this_CRM_TESTY_view_selected_args($stanowisko = null, $proces = null) {
		// procesy5.php?task=CRM_TESTY__ADD_TEST&proces_id=5039&test_type=TEORETYCZNY&stanowisko_id=21168
		if (!$proces && !$stanowisko) return;
		?>
<div class="panel panel-default">
  <div class="panel-heading">Wybrano:</div>
  <div class="panel-body">
		<ul>
			<?php if ($proces) : ?>
			<?php
				$changeLink = "procesy5.php?task=CRM_TESTY__ADD_TEST";
				if ($stanowisko) $changeLink .= "&stanowisko_id={$stanowisko->ID}";
			?>
			<li>
				Proces: <b class="text-danger">{<?php echo $proces->ID; ?>} <?php echo $proces->DESC; ?></b>
				<a class="btn btn-xs btn-default"
						 href="<?php echo $changeLink; ?>"><i class="glyphicon glyphicon-remove"></i> zmień</a>
			</li>
			<?php endif; ?>
			<?php if ($stanowisko) : ?>
			<?php
				$changeLink = "procesy5.php?task=CRM_TESTY__ADD_TEST";
				if ($proces) $changeLink .= "&proces_id={$proces->ID}&test_type=TEORETYCZNY";
			?>
			<li>
				Stanowisko: <b class="text-success">[<?php echo $stanowisko->ID; ?>] <?php echo $stanowisko->DESC; ?></b>
				<a class="btn btn-xs btn-default"
						 href="<?php echo $changeLink; ?>"><i class="glyphicon glyphicon-remove"></i> zmień</a>
			</li>
			<?php endif; ?>
		</ul>
  </div>
</div>
<?php
	}

	function this_CRM_TESTY_proces($proces, $stanowisko) {
		?>
<ol class="breadcrumb">
  <li><?php echo App::link("Testy", array('task'=>App::get_task())); ?></li>
  <li><?php echo App::link("Testy dla stanowiska ".'<span class="green">'.$stanowisko->DESC.'</span>', array('task'=>App::get_task(), 'stanowisko_id'=>$stanowisko->ID)); ?></li>
  <li class="active">Testy procesu <span class="red"><?php echo $proces->p__ID; ?></span></li>
</ol>
<?php

		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">'.$proces->p__ID.': ';print_r($proces);echo'</pre>';

		echo'<div class="box box-blue">';
		echo'<p>'."Dane osoby testujacej:".'</p>';
		echo'<form action="" method="post">';
			echo'<input type="hidden" name="function_init" value="'."fun_CRM_TESTY_ADD".'" />';
			echo'<p>';
				echo "Imie i nazwisko: ";
				echo'<input type="text" name="f_name" value="'.V::get('f_name', '', $_POST).'" class="i" size="50" />';
			echo'</p>';
			echo'<p>';
				echo "Nr telefonu: ";
				echo'<input type="text" name="f_tel" value="'.V::get('f_tel', '', $_POST).'" class="i" size="16" />';
			echo'</p>';
			echo'<p>';
				echo "Adres e-mail: ";
				echo'<input type="text" name="f_email" value="'.V::get('f_email', '', $_POST).'" class="i" size="50" />';
			echo'</p>';
			echo'<input type="submit" name="save_form" value="'."Rozpocznij test".'" />';
		echo'</form>';
		echo'</div>';// .box-blue
	}

	function this_CRM_TESTY_stanowisko($stanowisko) {
		$idProces = V::get('proces_id', 0, $_GET, 'int');
		$testType = V::get('test_type', '', $_GET);

		{// fetch procesy_init for group
			$procesInitList = array();
			$db = DB::getDB();
			$sql = "select p.`ID`, p.`PARENT_ID`, p.`TYPE`, p.`DESC`, p.`OPIS`, p.`TEST_SORT_PRIO`
				from `CRM_PROCES_idx_GROUP_to_INIT_VIEW` giv
					join `CRM_PROCES` as p on(p.`ID`=giv.`ID_PROCES_INIT`)
				where
					giv.`ID_GROUP`='{$stanowisko->ID}'
				order by p.`TEST_SORT_PRIO` desc, p.`ID` desc
			";
			$res = $db->query($sql);
			while ($r = $db->fetch($res)) {
				$procesInitList[$r->ID] = $r;
			}
		}

		if ($idProces > 0) {
			if (!array_key_exists($idProces, $procesInitList)) {
				?>
				<div class="alert alert-danger">
					Brak dostępu do procesu {<?php echo $idProces; ?>}!
					<br><a class="btn btn-xs btn-primary"
								 href="procesy5.php?task=CRM_TESTY__ADD_TEST&proces_id=<?php echo $idProces; ?>&test_type=<?php echo $testType; ?>">Wybierz inne stanowisko</a>
				</div>
<?php
			} else {
				$proces = $procesInitList[$idProces];
				this_CRM_TESTY_view_selected_args($stanowisko, $proces);
				$procesInitList = array($idProces => $proces);
				//this_CRM_TESTY_proces($procesInitList[$idProces], $stanowisko);
				//return;
			}
		} else {
			this_CRM_TESTY_view_selected_args($stanowisko, null);
		}

		echo '<h3>' . "Wybierz proces do przetestowania:" . '</h3>';
		if (empty($procesInitList)) {
			UI::alert('warning', "Brak danych");
			return;
		}
		?>
		<table class="table table-bordered table-hover">
			<thead>
				<tr>
					<th>Nr procesu</th>
					<th style="text-align:left">Nazwa / opis</th>
					<?php if (V::get('DBG_SORT', 0, $_GET)) echo '<th>SORT</th>'; ?>
				</tr>
			</thead>
			<tbody>
				<?php foreach ($procesInitList as $k_id => $v_proces) : ?>
				<tr>
					<td>
						<a class="btn btn-xs btn-warning"
							 href="procesy5.php?task=CRM_TESTY__ADD_TEST&function_init=fun_CRM_TESTY_ADD&stanowisko_id=<?php echo $stanowisko->ID; ?>&proces_id=<?php echo $v_proces->ID; ?>&test_type=TEORETYCZNY"
							 title="Uruchom test teoretyczny dla procesu <?php echo $v_proces->ID; ?>">Start <?php echo $v_proces->ID; ?> (Teoretyczny)</a>
					<?php if (User::get('ADM_ADMIN_LEVEL') < 6 && 'Kandydat' != User::get('EMPLOYEE_TYPE')) : ?>
						<br><br>
						<a class="btn btn-xs btn-primary"
							 href="procesy5.php?task=CRM_TESTY__ADD_TEST&function_init=fun_CRM_TESTY_ADD&stanowisko_id=<?php echo $stanowisko->ID; ?>&proces_id=<?php echo $v_proces->ID; ?>&test_type=PRAKTYCZNY"
							 title="Uruchom test praktyczny dla procesu <?php echo $v_proces->ID; ?>">Start <?php echo $v_proces->ID; ?> (Praktyczny)</a>
					<?php endif; ?>
					</td>
					<td>
						<b><?php echo $v_proces->DESC; ?></b>
						<br><em><?php echo $v_proces->OPIS; ?></em>
					</td>
					<?php if (V::get('DBG_SORT', 0, $_GET)) echo '<td>'.$v_proces->TEST_SORT_PRIO.'</td>'; ?>
				</tr>
				<?php endforeach; ?>
			</tbody>
		</table>
<?php
	}

	function this_print_tree_rec( $user_menu_tree, &$user_menu, $parent_id = null ) {
		if (empty($user_menu_tree) || !is_array($user_menu_tree)) {
			return;
		}
		$cls = ($parent_id === null)? ' class="user-menu-tree tree-wrap"' : '';
		echo '<ul' . $cls . '>';
		$list_total = count($user_menu_tree);
		foreach ($user_menu_tree as $k_id => $v_arr) {
			echo '<li ' . ((--$list_total)? '' : ' class="last"') . '>';
			if (array_key_exists($k_id, $user_menu)) {
				$z =& $user_menu[$k_id];
				echo '<span class="btn-box' . (($z->TYPE == 'STANOWISKO')? ' btn-box-red' : '') . '">' . $z->ID . '</span>';
				echo '<span class="desc">';
					echo '<b' . (($z->TYPE == 'STANOWISKO')? ' class="desc-red"' : '') . '>' . $z->TYPE . '</b>';
					echo ' ' . $z->DESC;
					echo ' <span class="more-desc">' . $z->OPIS . '</span> ';
				echo '</span> ';
				if ($z->TYPE == 'STANOWISKO') {
					echo App::link("Testy", "?stanowisko_id=" . $k_id, array('class'=>'btn-p5', 'title'=>'Przegladaj proces ' . $k_id));
				}
			} else {
				echo '<span class="btn-box">' . $k_id . '</span>';
			}
			if (!empty($v_arr)) {
				this_print_tree_rec($v_arr, $user_menu, $k_id);
			}
			echo '</li>';
		}
		echo '</ul>';
	}

	function this_tree_fetch_data_rec(&$userMenu, $userMenuTreeFlat) {
		$sqlIds = array();
		foreach ($userMenuTreeFlat as $kStanowiskoId => $vMenu) {
			if ($kStanowiskoId > 0) {
				$sqlIds[] = $kStanowiskoId;
			}
		}
		if (!empty($sqlIds)) {
			$db = DB::getDB();
			$sql = "select
					z.`ID`, z.`PARENT_ID`, z.`DESC`, z.`OPIS`, z.`TYPE`
				from `CRM_LISTA_ZASOBOW` as z
				where
					z.`ID` in (" . implode(", ", $sqlIds) . ")
			";
			$res = $db->query($sql);
			while ($r = $db->fetch($res)) {
				$userMenu[$r->ID] = $r;
			}
		}
	}

	// choose STANOWISKO
	$stanowiska = array();

	// TODO: model->get_stanowiska_list()
	$db = DB::getDB();
	$sqlWhereAdd = "";
	if (!User::hasAccess('procesy') && User::hasAccess('testy')) {
		$usrStanowiska = User::getGroups();
		if (empty($usrStanowiska)) {
			UI::startContainer();
			UI::alert('danger', "Brak przypisanego stanowiska");
			UI::endContainer();
			return;
		}
		$sqlUsrStanowiskaId = implode(',', array_keys($usrStanowiska));
		$sqlWhereAdd = " and z.`ID` in({$sqlUsrStanowiskaId}) ";
	}
	if ($idProces > 0) {
		$usrStanowiska = User::getGroups();
		if (empty($usrStanowiska)) {
			UI::startContainer();
			UI::alert('danger', "Brak przypisanego stanowiska");
			UI::endContainer();
			return;
		}
		$sqlUsrStanowiskaId = implode(',', array_keys($usrStanowiska));
		$sqlWhereAdd = " and z.`ID` in (
				select giv.`ID_GROUP`
				from `CRM_PROCES_idx_GROUP_to_INIT_VIEW` giv
				where giv.`ID_PROCES_INIT` = '{$idProces}'
					and giv.`ID_GROUP` in({$sqlUsrStanowiskaId})
			)
		";
	}
	$sql = "select z.`ID`, z.`PARENT_ID`, z.`DESC`, z.`OPIS`, z.`TYPE`
		from `CRM_LISTA_ZASOBOW` as z
		where
			z.`TYPE`='STANOWISKO'
			{$sqlWhereAdd}
		order by z.`ID` desc
	";
	$res = $db->query($sql);
	while ($r = $db->fetch($res)) {
		$stanowiska[$r->ID] = $r;
	}

	$stanowisko_id = V::get('stanowisko_id', 0, $_GET, 'int');
	if ($stanowisko_id > 0) {
		if (!array_key_exists($stanowisko_id, $stanowiska)) {
			UI::startContainer();
			UI::alert('danger', "Twoje konto nie jest przypisane do stanowiska [{$stanowisko_id}]. Poszę wybrać inne stanowisko.");
			UI::endContainer();
		} else {
			// show testy dla stanowiska
			this_CRM_TESTY_stanowisko($stanowiska[$stanowisko_id]);
			return;
		}
	}

	$taskName = App::get_task();
	$stanowiskaList = array();
	foreach ($stanowiska as $kNr => $r) {
		$stanowiskaList[$kNr] = "[{$r->ID}] {$r->DESC} {$r->OPIS}";
	}

	if ($idProces > 0) {
		$db = DB::getDB();
		$proces = $db->get_by_id('CRM_PROCES', $idProces);
		if ($proces && $proces->TYPE == 'PROCES_INIT') {
			this_CRM_TESTY_view_selected_args(null, $proces);
		}
	}

	?>
	<h3>Wybierz stanowisko do przetestowania:</h3>

	<form class="form-horizontal">
		<input type="hidden" name="task" value="<?php echo $taskName; ?>" />
		<?php if ($idProces) : ?>
			<input type="hidden" name="proces_id" value="<?php echo $idProces; ?>" />
		<?php endif; ?>
		<?php if ($testType) : ?>
			<input type="hidden" name="test_type" value="<?php echo $testType; ?>" />
		<?php endif; ?>
		<div class="form-group">
			<div class="col-sm-10">
				<select class="form-control"
								name="stanowisko_id"
								size="<?php echo (count($stanowiskaList) > 10)? 20 : count($stanowiskaList) + 1;?>">
					<?php foreach ($stanowiskaList as $kNr => $stanowiskoLabel) : ?>
						<option value="<?php echo $kNr; ?>"><?php echo $stanowiskoLabel; ?></option>
					<?php endforeach; ?>
				</select>
			</div>
		</div>
		<div class="form-group">
			<div class="col-sm-2">
				<input class="btn btn-primary" type="submit" value="Wybierz" />
			</div>
		</div>
	</form>
	<?php
	$tree_flat = array();
	foreach ($stanowiska as $k_id => $r) {
		$tree_flat[$r->ID] = null;
		$tree_flat[$r->PARENT_ID] = null;
	}

	$tree_created = TreeHelper::build_tree_flat('CRM_LISTA_ZASOBOW', $tree_flat);
//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">{'.$tree_created.'} Tree flat: ';print_r($tree_flat);echo'</pre>';

	$stanowiska_tree = TreeHelper::get_tree_from_flat($tree_flat);
//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">stanowiska_tree: ';print_r($stanowiska_tree);echo'</pre>';

	this_tree_fetch_data_rec($stanowiska, $tree_flat);
//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">stanowiska all: ';print_r($stanowiska);echo'</pre>';
	//DEBUG_S(1,'user_menu',$user_menu, __FILE__, __FUNCTION__, __LINE__);

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

	this_print_tree_rec($stanowiska_tree[0], $stanowiska);
}


/**
 * Router for task_CRM_TESTY__LIST, task_CRM_TESTY__ADD_KANDYDAT, task_CRM_TESTY__ADD_TEST
 * @param $_GET['stanowisko_id']
 * @param $_GET['proces_id']
 */
function task_CRM_TESTY() {
	if (!User::hasAccess('testy')) {
		User_procesy5_check_access();
	}

	$tasks = array();
	$tasks[] = App::link("Twoje testy", array('task'=>"CRM_TESTY__LIST"), array('class'=>'btn-p5'));
	if (User::hasAccess('procesy')) {
		$tasks[] = App::link("Dodaj Kandydata i zaloguj się do testów", array('task'=>"CRM_TESTY__ADD_KANDYDAT"), array('class'=>'btn-p5'));
	}
	$tasks[] = App::link("Uruchom nowy test", array('task'=>"CRM_TESTY__ADD_TEST"), array('class'=>'btn-p5'));

	$myTestsLink = App::build_http_query(array('task'=>"CRM_TESTY__LIST"));
	$newTestLink = App::build_http_query(array('task'=>"CRM_TESTY__ADD_TEST"));
	$addUserLink = null;
	if (User::hasAccess('procesy')) {
		$addUserLink = App::build_http_query(array('task'=>"CRM_TESTY__ADD_KANDYDAT"));
	}
	?>
	<div class="container" style="text-align:center;padding-top:20px">
		<a class="btn btn-lg btn-info" href="<?php echo $myTestsLink; ?>">Twoje testy</a>
		<a class="btn btn-lg btn-primary" href="<?php echo $newTestLink; ?>">Uruchom nowy test</a>
		<?php if ($addUserLink) : ?>
			<a class="btn btn-lg btn-danger" href="<?php echo $addUserLink; ?>">Dodaj Kandydata i zaloguj się do testów</a>
		<?php endif; ?>
	</div>
<?php
}


/**
 * Por??wnuje wyniki zaznaczonych test??w.
 * @param $_COOKIE['TESTY_WYNIKI_COMPARE'] - array of TEST_ID
 *   if all TEST_ID has the same Proces ID then compare, alse show list.
 */
function task_CRM_TESTY_WYNIKI_COMPARE() {
	$testy_id = V::get('TESTY_WYNIKI_COMPARE', '', $_COOKIE);
	$testy_id = trim($testy_id);
	if (empty($testy_id)) {
		echo'<p class="red">'."Brak zaznaczonych testow".'</p>';
		return;
	}

	$testy_id = explode(' ', trim($testy_id));
	echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">';print_r($testy_id);echo'</pre>';
}


function task_CRM_TESTY_WYNIKI() {
	if (User::hasAccess('testy_wyniki_read')) {
		User_procesy5_check_access();
	}

	$kandydat_id = V::get('kandydat_id', 0, $_GET, 'int');
	$test_id = V::get('test_id', 0, $_GET, 'int');

	// TODO: if kandydat_id - lista testow kandydata, btn ocen jesli NORMAL
	// TODO: if kandydat_id and test_id - ocen test jesli NORMAL

	//TODO: uprawnienia - tester nie moze oceniac!
	if (!User::hasAccess('testy_wyniki')) {
		echo'<p class="red">'."Brak uprawnien!".'</p>';
		return;
	}

	echo '<table style="margin:7px 0; border-bottom:1px solid #666;">';
	echo '<tr>';
	echo '<td style="padding:0 10px 0 0; vertical-align:top;">';
	Lib::loadClass('ProcesTestyHelper');
	{
		$params = array();
		$params ['order by'] = "ADM_NAME";
		$kandydaci = ProcesTestyHelper::get_kandydaci( $params );
		echo'<h3 style="margin:0 0 5px 0;">'."Wybierz kandydata".'</h3>';
		echo'<form action="" method="get">';
			echo'<input type="hidden" name="task" value="'.App::get_task().'" />';
			//$kandydaci_cnt = count($kandydaci);
			$sel_size = 10;// ($kandydaci_cnt < 10)? $kandydaci_cnt : 10;
			echo'<select name="kandydat_id" size="'.$sel_size.'" onchange="this.form.submit()">';
				echo'<option value="">'." [ Wybierz ] ".'</option>';
			foreach ($kandydaci as $r) {
				$sel = ($kandydat_id == $r->ID)? 'selected="selected"' : '';
				echo'<option value="'.$r->ID.'"'.$sel.'>'."".$r->ADM_NAME." [".$r->ID."] (".$r->ADM_PHONE.", ".$r->ADM_OTHER_INFO.")".'</option>';
			}
			echo'</select>';
			echo '<br />';
			echo' <input type="submit" value="'."Wybierz".'" />';
		echo'</form>';
	}
	echo '</td>';
	echo '<td style="padding:0 0 0 10px; border-left:1px solid #666; vertical-align:top;">';
	Lib::loadClass('UsersHelper');
	{
		$params = array();
		$pracownicy = UsersHelper::get_users_list($params, 0, 0, 'ADM_NAME', 'ASC');
		echo'<h3 style="margin:0 0 5px 0;">'."lub pracownika".'</h3>';
		echo'<form action="" method="get">';
			echo'<input type="hidden" name="task" value="'.App::get_task().'" />';
			//$pracownicy_cnt = count($pracownicy);
			$sel_size = 10;// ($pracownicy_cnt < 10)? $pracownicy_cnt : 10;
			echo'<select name="kandydat_id" size="'.$sel_size.'" onchange="this.form.submit()">';
				echo'<option value="">'." [ Wybierz ] ".'</option>';
			foreach ($pracownicy as $r) {
				$sel = ($kandydat_id == $r->ID)? 'selected="selected"' : '';
				echo'<option value="'.$r->ID.'"'.$sel.'>'."".$r->ADM_NAME." [".$r->ID."] (".$r->ADM_PHONE.", ".$r->ADM_OTHER_INFO.")".'</option>';
			}
			echo'</select>';
			echo '<br />';
			echo' <input type="submit" value="'."Wybierz".'" />';
		echo'</form>';
	}
	echo '</td>';
	echo '</tr>';
	echo '</table>';

	if ($kandydat_id > 0) {
		//echo'<span style="margin:0 0 0 30px;">';
		echo App::link("Certyfikat", array('task'=>'CRM_TESTY_WYNIKI_CERTYFIKAT', 'kandydat_id'=>$kandydat_id, 'HIDE_PANEL'=>1), array('target'=>'_blank', 'ico_after_text'=>'print'));
		//echo'</span>';
		echo '<br />';
	}

	if ($test_id <= 0) {
		echo'<script type="text/javascript">'."
function compareAdd(id){
	var c=jQuery.cookie('TESTY_WYNIKI_COMPARE')
	if(compareExists(id)){
		if(c==='' || c===null){ c=''+id; }else{ c=''+id+' '+c; }
		jQuery.cookie('TESTY_WYNIKI_COMPARE', c)
	}
}
function compareExists(id){
	var c=jQuery.cookie('TESTY_WYNIKI_COMPARE')
	return ((' ' + c + ' ').indexOf(' ' + id + ' ') == -1)
}
function compareRm(id){
	var c=jQuery.cookie('TESTY_WYNIKI_COMPARE')
	var carr=c.split(' ')
	jQuery.unique( carr )
	c = (' '+carr.join(' ')+' ').replace((new RegExp(' '+id+' ', 'g')), ' ')
	c = jQuery.trim(c)
	jQuery.cookie('TESTY_WYNIKI_COMPARE', c)
}
function compareClear(id){
	jQuery.cookie('TESTY_WYNIKI_COMPARE', '');
}

function compareCheckbox(n,id){
	if(n.checked){
		compareAdd(id)
	}else{
		compareRm(id)
	}
}
		".'</script>';
		//echo App::link("CRM_TESTY_WYNIKI_COMPARE", array('task'=>"CRM_TESTY_WYNIKI_COMPARE"));

		$params = array();
		$params['limit'] = V::get('_limit', 20, $_GET, 'int');
		$params['offset'] = V::get('_offset', 0, $_GET, 'int');
		$params['order_by'] = V::get('_order_by', 'ID', $_GET);
		$params['order_dir'] = V::get('_order_dir', 'DESC', $_GET);
		if ($kandydat_id > 0) {
			$params['id_tester'] = $kandydat_id;
		}
		$params['organizer_name'] = true;

		// validate params
		if ($params['offset'] < 0) $params['offset'] = 0;

		$lista_cnt = ProcesTestyHelper::get_testy_total( $params );
		if ($lista_cnt <= 0) {
			echo "Brak testów";
			return;
		}
		if ($params['offset'] > $lista_cnt) $params['offset'] = $lista_cnt - ($lista_cnt % $params['limit']);

		$testy_arr = ProcesTestyHelper::get_testy( $params );
		$cols = array();
		$cols ['ID'] = "ID";
		$cols ['TEST_TYPE'] = "Rodzaj testu";
		$cols ['Kandydat'] = "Kandydat";
		$cols ['ID_PROCES_INIT'] = "Proces ID";
		$cols ['Stanowisko'] = "Stanowisko";
		$cols ['TEST_INIT'] = "Rozpoczeto czytanie";
		$cols ['TEST_START'] = "Rozpoczeto odpowiadanie";
		$cols ['TEST_END'] = "Zakonczono";
		$cols ['OCENA'] = "Ocena";
		$cols ['COST'] = "Koszt";
		$cols ['DISCOUNT'] = "Rabat";
		$cols ['TEST_PLACE'] = "Miejsce";
		$cols ['Organizer'] = "Organizator";
		$cols ['UWAGI'] = "Uwagi";
		$cols ['SHOW_IN_CERT'] = "Pokaż na cert.";

		echo '<style type="text/css">' . "
.cell-test_type-teoretyczny {background-color:#FFCA9B;}
.cell-test_type-praktyczny {background-color:#B3EBFB;}
		" . '</style>';

		echo '<p>' . '<b style="font-size:1.17em;">' . "Wybierz test " . '</b>' . " - ";
		echo App::link("Ustal kolejność testów", array('task'=>'TEST_SORT'));
		echo '</p>';
		echo'<table cellspacing="0" cellpadding="0" class="tbl-view" border="1">';
		echo'<thead>';
			echo'<tr>';
			foreach ($cols as $k => $v) {
				echo'<th>'.$v.'</th>';
			}
			echo'<th>'."&nbsp;".'</th>';
			echo'</tr>';
		echo'</thead>';
		echo'<tfoot>';
			echo'<td colspan="'.(count($cols) + 1).'">';
				$page_nav = new stdClass();
				$page_nav->total = $lista_cnt;
				$page_nav->limit = $params['limit'];
				$page_nav->current = $params['offset'];
				$page_nav->offset_start = 0;
				$page_nav->offset_prev = $page_nav->current - $page_nav->limit;
				$page_nav->offset_next = $page_nav->current + $page_nav->limit;
				$page_nav->offset_end = floor($lista_cnt / $page_nav->limit) * $page_nav->limit;
				$link_params = array('task'=>App::get_task(), '_offset'=>$page_nav->offset_start);
				if ($kandydat_id > 0) $link_params['kandydat_id'] = $kandydat_id;
				echo App::link("&lt;&lt;", $link_params, array('class'=>'btn-p5'));
				$link_params = array('task'=>App::get_task(), '_offset'=>$page_nav->offset_prev);
				if ($kandydat_id > 0) $link_params['kandydat_id'] = $kandydat_id;
				echo ' '.App::link("&lt; -".$page_nav->limit, $link_params, array('class'=>'btn-p5'));
				echo ' '.$page_nav->current.' ('.$page_nav->total.') ';
				$link_params = array('task'=>App::get_task(), '_offset'=>$page_nav->offset_next);
				if ($kandydat_id > 0) $link_params['kandydat_id'] = $kandydat_id;
				echo ' '.App::link("+".$page_nav->limit." &gt;", $link_params, array('class'=>'btn-p5'));
				$link_params = array('task'=>App::get_task(), '_offset'=>$page_nav->offset_end);
				if ($kandydat_id > 0) $link_params['kandydat_id'] = $kandydat_id;
				echo ' '.App::link("&gt;&gt;", $link_params, array('class'=>'btn-p5'));
			echo'</td>';
		echo'</tfoot>';
		echo'<tbody>';
		if (!empty($testy_arr)) {
			foreach ($testy_arr as $r) {
				echo'<tr>';
					foreach ($cols as $k => $v) {
						if ($k == 'COST' || $k == 'DISCOUNT') {
							echo '<td>' . number_format($r->$k, 2, ',', '') . '</td>';
						} else {
							$cls = '';
							if ($k == 'TEST_TYPE') {
								$cls = 'cell-' . strtolower($k) . '-' . strtolower($r->$k);
							}
							if ($cls) $cls = ' class="' . $cls . '"';
							echo '<td' . $cls . '>' . $r->$k . '</td>';
						}
					}
					echo'<td>';
					if (User::get('ADM_ADMIN_LEVEL') == 0 && $r->A_STATUS == 'OFF_HARD') {// tylko level 0 i ocenione testy
						// edit link
						echo App::link("edit", array('task'=>"CRM_TESTY_WYNIKI_EDIT", 'test_id'=>$r->ID), array('title'=>"Edytuj", 'ico'=>'edit'));
					}
					// ocena
					if ($r->A_STATUS == 'WAITING') {
						//echo'Test nie rozpoczety';
					} else if ($r->A_STATUS == 'MONITOR') {
						//echo'Test rozpoczeto '.$r->TEST_INIT;
					} else if ($r->A_STATUS == 'NORMAL') {
						//echo'Test zakonczono '.$r->TEST_END;
						echo App::link("ocen odpowiedzi", array('task'=>'CRM_TESTY_WYNIKI', 'test_id'=>$r->ID, 'kandydat_id'=>$r->ID_TESTER), array('class'=>'btn-p5'));
					} else if ($r->A_STATUS == 'OFF_HARD') {
						echo App::link("odpowiedzi", array('task'=>'CRM_TESTY_WYNIKI', 'test_id'=>$r->ID, 'kandydat_id'=>$r->ID_TESTER), array('class'=>'btn-p5'));
					} else {
						//echo '{'.$r->A_STATUS.'}';
					}
// TODO: checked from $_COOKIE['']
//$js = "compareCheckbox(this,'".$r->ID."')";
//echo'<input type="checkbox" value="'.$r->ID.'" onclick="'.$js.'" />';
					echo'</td>';
				echo'</tr>';
			}
			echo'</tbody>';
			echo'</table>';
		}
	}

	if ($kandydat_id > 0 && $test_id > 0) {
		echo '<hr />';

		$test_obj = DB::get_by_id('CRM_TESTY', $test_id);

		$odpowiedzi = ProcesTestyHelper::get_odpowiedzi($test_obj->ID, $test_obj->TEST_TYPE);

		$tbl = 'CRM_PROCES';
		$clbk = 'tree_callback__show_wynik_item_from_' . $tbl;

		$tree_params = array();
		$tree_params['rozwin'] = true;
		$tree_params['editable'] = false;
		$tree_params['rozwin_proces'] = true;
		$tree_params['filtr_img'] = true;
		$tree_params['rozwin_zasoby'] = true;
		$tree_params['rozwin_opis'] = true;
		$tree_params['style'] = 'NOWY';
		$tree_params['show_ocen'] = true;
		$tree_params['TEST_TYPE'] = $test_obj->TEST_TYPE;
		foreach ($odpowiedzi as $k_id_proces => $v_odp) {
			foreach ($v_odp as $k_id_pyt => $v_pyt) {
				$tree_params[ 'ODP_'.$k_id_pyt ] = $v_pyt->ODPOWIEDZ;
				for ($i = 0; $i < 5; $i++) {
					$v_pyt_field = "ODP_".$i;
					$tree_params[ 'ODP_'.$k_id_pyt.'_ODP_'.$i ] = $v_pyt->$v_pyt_field;
				}
				$tree_params[ 'ocena_'.$k_id_pyt ] = $v_pyt->OCENA;
			}
		}
		echo '<form action="" method="post">';
		echo '<input type="hidden" name="function_init" value="' . "fun_CRM_TEST_EDIT" . '" />';
		echo '<input type="hidden" name="subtask" value="' . "OCEN" . '" />';

		action_VIEW_SUBTREE($tbl, $test_obj->ID_PROCES_INIT, $clbk, $tree_params);

		echo '<div class="box box-blue">';
		if ($test_obj->OCENA > 0) echo '<span class="blue">' . "Wynik: <b>" . $test_obj->OCENA . "</b> / 3. " . '</span><br />';
		echo "Uwagi do oceny:";
		echo '<br />';
		echo '<textarea name="f_uwagi" cols="100" rows="7">' . $test_obj->UWAGI . '</textarea>';
		echo '<br />';
		echo '<input type="submit" name="ocen" value="' . "Zapisz" . '" />';
		echo '</div>';// .box-blue

		echo '</form>';
	}
}


function fun_CRM_TESTY_RM_PYTANIE() {
	$redirect = "?task=".App::get_task();
	$msg = '';
	$arg_id = V::get('id', 0, $_GET, 'int');
	$arg_id_proces = V::get('id_proces', 0, $_GET, 'int');

	if ($arg_id_proces <= 0 || $arg_id <= 0) {
		App::add_error("Wrong ID");
		App::redirect($redirect, $msg);
		exit;
	}
	$redirect .= "&id_proces=".$arg_id_proces;

	$arg_type = V::get('_type', '', $_REQUEST);
	$redirect .= "&_type=".$arg_type;

	Lib::loadClass('ProcesTestyHelper');
	$affected = ProcesTestyHelper::delete_pytanie( $arg_id, $arg_id_proces );
	if ($affected == 1) {
		App::add_msg("Usunieto pytanie ID=".$arg_id);
	} else {
		App::add_error("Wystapil blad podczas usuwania zdjecia ID=".$arg_id);
	}
	App::redirect($redirect, $msg);
}


function fun_CRM_TESTY_ADD_PYTANIE() {
	$redirect = "?task=".App::get_task();
	$msg = '';
	$sql_obj = new stdClass();
	$prefix = 'add_';
	$arg_id_proces = V::get('id_proces', 0, $_GET, 'int');
	if ($arg_id_proces <= 0) {
		App::add_error("Wrong ID");
		App::redirect($redirect, $msg);
		exit;
	}
	$arg_id_wskaznik = V::get('id_wskaznik', 0, $_GET, 'int');
	$arg_id_wskaznik = V::get($prefix.'ID_WSKAZNIK', $arg_id_wskaznik, $_POST, 'int');

	$arg_type = V::get('_type', '', $_REQUEST);
	// TODO: validate

	$redirect .= "&_type=".$arg_type;
	$redirect .= "&id_proces=".$arg_id_proces;
	if ($arg_id_wskaznik > 0) {
		$redirect .= "&id_wskaznik=".$arg_id_wskaznik;
	}
	$sql_obj->TEST_TYPE = $arg_type;
	$sql_obj->ID_PROCES = $arg_id_proces;
	$sql_obj->ID_WSKAZNIK = $arg_id_wskaznik;
	$sql_obj->PYTANIE = V::get($prefix.'PYTANIE', '', $_POST);
	for ($i = 0; $i < 5; $i++) {
		$field = "ODP_".$i;
		$sql_obj->$field = V::get($prefix.$field, '', $_POST);
		$field = "ODP_".$i."_ODP";
		$sql_obj->$field = V::get($prefix.$field, '', $_POST);
	}

	$error = false;
	if (!$sql_obj->PYTANIE) {
		App::add_error("Podaj tresc pytania");
		$error = true;
	}

	if ($error) {
		App::redirect($redirect, $msg);
		return;
	}

	$new_id = DB::ADD_NEW_OBJ( 'CRM_TESTY_PYTANIA', $sql_obj );
	if ($new_id > 0) {
		App::add_msg("Dodano nowe pytanie");
	}
	else {
		App::add_error("Blad podczas dodawania nowego pytania!");
	}
	App::redirect($redirect, $msg);
}


function task_CRM_TESTY_ADD_PYTANIA() {
	$id_proces = V::get('id_proces', 0, $_REQUEST, 'int');
	$id_pytanie = V::get('id_pytanie', 0, $_REQUEST, 'int');
	$id_wskaznik = V::get('id_wskaznik', 0, $_REQUEST, 'int');
	$_type = V::get('_type', 0, $_REQUEST);

	Lib::loadClass('ProcesTestyHelper');
	$types_allowed = ProcesTestyHelper::get_allowed_types();
	if (!array_key_exists($_type, $types_allowed)) {
		$_type = false;
	}

	{// pathway
	echo'<h1>';
		echo App::link("Procesy", array('task'=>"CRM_PROCES"));
		if ($id_proces > 0) {
			echo ' &raquo; '.App::link("Pytania dla procesu [".$id_proces."]", array('task'=>App::get_task(), 'id_proces'=>$id_proces, '_type'=>$_type));
			if ($id_wskaznik > 0) {
				echo ' &raquo; '.App::link("dla wskaznika [".$id_wskaznik."]", array('task'=>App::get_task(), 'id_proces'=>$id_proces, 'id_wskaznik'=>$id_wskaznik, '_type'=>$_type));
			}
		}
	echo'</h1>';
	}// pathway

	if ($id_proces <= 0) {
		echo'<div class="box box-red">';
			echo "Wrong ID";
		echo'</div>';
		return;
	}

	$proces = DB::get_by_id( 'CRM_PROCES', $id_proces );
	if (!$proces) {
		echo'<div class="box box-red">';
			echo "Proces [".$id."] not exists.";
		echo'</div>';
		return;
	}

	Lib::loadClass('ProcesHelper');
	{// proces info
	$wsk = ProcesHelper::get_wskazniki( $proces->ID );
	echo'<div class="tree-wrap">';
	echo'<ul>';
	echo'<li class="last">';
	echo'<dl>';
	echo'<dt>';
	if (!empty($wsk)) echo'<div class="has_wsk">';
		echo'<b class="item_id btn-box">'.$proces->ID.'</b>';
		echo'<span class="desc"><b>'.$proces->DESC.'</b>';
			echo'<span class="more-desc"> '.$proces->OPIS.' </span>';
		echo'</span>';
	if (!empty($wsk)) echo'</div>';
	echo'</dt>';
	if (!empty($wsk)) {
		$zasoby_id = array();
		echo'<dd>';
		echo'<ul>';
		$wsk_cnt = count( $wsk );
		foreach ($wsk as $w) {

			$w_parents_out = '';
			$w_title_parents_out = '';

			echo'<li'.((--$wsk_cnt)? '' : ' class="last"').'>';
			echo'<p>';
			echo ' <span class="btn-box btn-box-silver">'.$w->CW_ID.'</span>';
			echo App::link("P+", array('task'=>App::get_task(), 'id_proces'=>$proces->ID, 'id_wskaznik'=>$w->CW_ID, '_type'=>$_type, '#'=>'frm-pytanie-add'), array('title'=>"Dodaj pytanie do wskaznika ".$w->CW_ID, 'class'=>'btn-p5'));
			echo ' <span class="green"'.$w_title_parents_out.'>['.$w->ID.']</span>';
			echo ' <i title="'.$w->CP_PYTANIE.' '.$w->CP_OPIS.'">'.$w->CP_FORM_TREAT.'</i>';
			echo '';
			echo ' '.$w->TYPE.'';
			if ($w->DESC_PL) {
				echo ' <em>'.$w->DESC.'</em> <b>'.$w->DESC_PL.'</b> ';
			} else {
				echo ' <p>'.$w->DESC.'</p> ';
			}

			//if ($tree->get_param('rozwin_opis'))
			echo ' <span class="green">'.$w->OPIS.'</span>';// opis zasobu
			//if ($tree->get_param('rozwin_opis'))
			echo ' <span style="color:#000;">'.$w->OPIS_ZASOB.'</span>';// komentarz wskaznika

			echo'</p>';
			echo'</li>';
		}
		echo'</ul>';
	}
	echo'</dl>';
	echo'</li>';
	echo'</ul>';
	echo'</div>';// .tree-wrap
	}// proces info

	// type
	echo '<style type="text/css">' . "
.col-btns{text-align:left; vertical-align:top; padding:5px;}
.test-teoretyczny {color:#9E4C03; font-weight:bold;}
.test-praktyczny {color:#047B9E; font-weight:bold;}
a.btn-test-teoretyczny {background-color:#FFCA9B;}
a.btn-test-praktyczny {background-color:#B3EBFB;}
	" . '</style>';
	echo '<p>' . '<b>' . "Typ pytania: " . '</b>';
	//if (!$_type) {
		echo '<ul>';
		$type_base_link = array();
		$type_base_link ['task'] = App::get_task();
		$type_base_link ['id_proces'] = $id_proces;
		if ($id_pytanie > 0) $type_base_link ['id_pytanie'] = $id_pytanie;
		if ($id_wskaznik > 0) $type_base_link ['id_wskaznik'] = $id_wskaznik;
		foreach ($types_allowed as $k_type => $v_label) {
			$st = '';
			if ($_type) {
				//$st = ($_type == $k_type)? ' style="font-weight:bold; color:green"' : ' style="color:#666;"';
				$st = ($_type == $k_type)? ' class="' . "test-" . strtolower($k_type) . '"' : ' style="color:#666;"';
			}
			echo '<li'.$st.'>';
			if ($_type && $_type == $k_type) {
				echo $v_label;
			}
			else {
				echo '<span class="' . "test-" . strtolower($k_type) . '">' . $v_label . '</span>' . " - ";
				echo App::link("ustaw", V::extend($type_base_link, array('_type'=>$k_type)), array('class'=>'btn-p5 btn-test-'.strtolower($k_type)));
			}
			echo '</li>';
		}
		echo '</ul>';
	//} else {
	//	echo '<b style="color:green">' . $types_allowed[$_type] . '</b>';
	//}
	echo '</p>';
	if (!$_type) {
		return;
	}
	echo '<hr />';

	function this_print_form_pytanie( &$r, $prefix, $id_pytanie_current_edit, $_type ) {
		$out = '';
		$this_edit = false;
		if ($prefix != 'add_') {
			if ($id_pytanie_current_edit > 0 && $r->ID == $id_pytanie_current_edit) {
				$this_edit = true;
			}
		}
		$sent_key = $prefix.'sent';
		if ($this_edit && V::get($sent_key, '', $_POST)) {
			//TODO: add/edit ; function init ?
			$field = "PYTANIE";
			$r->$field = V::get( $prefix.$field, '', $_POST);
			$field = "ID_WSKAZNIK";
			$r->$field = V::get( $prefix.$field, '', $_POST, 'int');
			for ($i = 0; $i < 5; $i++) {
				$field = "ODP_".$i;
				$r->$field = V::get( $prefix.$field, '', $_POST);
				$field = "ODP_".$i."_ODP";
				$r->$field = V::get( $prefix.$field, '', $_POST);
			}//end for

			// TODO: validate
			$errors = array();

			if (empty($errors)) {
				$sql_obj = new stdClass();
				$sql_obj->TEST_TYPE = $_type;
				foreach (get_object_vars($r) as $key => $val) {
					$sql_obj->$key = $val;
				}
				if ($prefix == 'add_') {
					//$sql_ret = DB::ADD_NEW_OBJ( 'CRM_TESTY_PYTANIA', $sql_obj );
					//if ($sql_ret > 0) {
					//	echo '<p class="green box box-green">'."Dodano nowy rekord [$sql_ret]".'</p>';
					//	return true;// exception
					//} else {
					//	echo '<p class="err box box-red">'."Blad podczas dodawania nowego rekordu".'</p>';
					//}
				} else {
					$sql_affected = DB::UPDATE_OBJ( 'CRM_TESTY_PYTANIA', $sql_obj );
					if ($sql_affected == 2) {
						echo '<p class="green box box-green">'."Zmienio rekord".'</p>';
					} else if ($sql_affected == 1) {
						echo '<p class="err box box-red">'."Zmieniono rekord (Error: nie zapisano hostorii)".'</p>';
					} else if ($sql_affected < 0) {
						echo '<p class="err box box-red">'."Blad podczas edytowania rekordu - nic nie zmieniono".'</p>';
					}
				}
			}
		}

		if ($prefix == 'add_') {
			unset($r->ID);
		} else {
			//$r->ID = V::get( $prefix.'ID', '', $_POST );
		}

		if ($prefix == 'add_') {
			$out .= '<hr id="frm-pytanie-add" style="margin:18px 0;" />';
			$out .= '<div class="box">';// box-hover-active
			$out .= '<form action="" method="post" style="margin:0;">';
			$out .= '<input type="hidden" name="'.$sent_key.'" value="'."1".'" />';
			$out .= '<b class="blue">'."Dodaj nowe pytanie (" . $_type . ").".'</b>'." ";
			$out .= '<input type="hidden" name="'."function_init".'" value="'."fun_CRM_TESTY_ADD_PYTANIE".'" />';
			$out .= '<input type="hidden" name="'."ID_PROCES".'" value="'.$r->ID_PROCES.'" />';
			$out .= '<input type="hidden" name="' . "_type" . '" value="' . $_type . '" />';
			if ($r->ID_WSKAZNIK > 0) {
				$wsk = ProcesHelper::get_wskazniki( $r->ID_PROCES );
				if (array_key_exists($r->ID_WSKAZNIK, $wsk)) {
				} else {
					$r->ID_WSKAZNIK = 0;
				}
			}
			{
				$field = "ID_WSKAZNIK";
				$out .= '<span class="green">'."Wskaznik: ".'</span>';
				$out .= '<input type="text" name="'.$prefix.$field.'" value="'.$r->ID_WSKAZNIK.'" size="6" />';
				$out .= ' <i class="silver">(id wskaznika lub 0)</i>';
			}
			$out .=  '<br />'."Tresc pytania: ";
			$field = "PYTANIE";
			$out .=  '<br />'.'<textarea name="'.$prefix.$field.'" cols="90" rows="3">'.htmlspecialchars($r->$field).'</textarea>';
			for ($i = 0; $i < 5; $i++) {
				$field = "ODP_".$i;
				$out .= '<p style="margin:0 2px;">';
					$out .=  "".($i + 1).". odpowiedz: ";
					$out .= '<input type="text" name="'.$prefix.$field.'" value="'.htmlspecialchars($r->$field).'" size="70" maxlength="100" />';
					$out .=  " poprawna: ";
					$field = "ODP_".$i."_ODP";
					$out .= '<select name="'.$prefix.$field.'">';
					$options = array("", "TAK", "NIE");
					foreach ($options as $k) {
						$sel = ($r->$field == $k)? ' selected="selected"' : '';
						$out .= '<option value="'.$k.'"'.$sel.'>'.$k.'</option>';
					}
					$out .= '</select>';
				$out .= '</p>';
			}
			$sbmt_value = 'Zapisz';
			if ($prefix == 'add_') $sbmt_value = 'Dodaj';
			$out .= '<input type="submit" value="'.$sbmt_value.'" />';
			$out .= '</form>';
			$out .= '</div>';// .box
		}
		else {// edit or view only
			$attr_readonly = ($this_edit)? '' : ' readonly="readonly"';
			$st = ($this_edit)? ' style="border-color:blue;"' : ' style="background:#eee;"';
			$out .= '<div class="box"'.$st.'>';// box-hover-active
			if ($this_edit) {
				$out .= '<form action="" method="post" style="margin:0;">';
				$out .= '<input type="hidden" name="'.$sent_key.'" value="'."1".'" />';
				$out .= '<input type="hidden" name="'."ID".'" value="'.$r->ID.'" />';
			}
			$js_onclick = "return confirm('Czy na pewno usunac pytanie ".$r->ID." do procesu ".$r->ID_PROCES."?');";
			$out .= App::link("delete", array('function_init'=>"fun_CRM_TESTY_RM_PYTANIE", 'id'=>$r->ID, 'id_proces'=>$r->ID_PROCES, '_type'=>$_type), array('title'=>"Usun pytanie", 'ico'=>'del.png', 'onclick'=>$js_onclick));
			if (!$this_edit) {
				$js_onclick = ($id_pytanie_current_edit > 0)? "return confirm('Uwaga edytujesz pytanie ".$id_pytanie_current_edit.". Zmiany nie zostana zapisane!');" : "";
				$out .= App::link("edit", array('task'=>App::get_task(), 'id_pytanie'=>$r->ID, 'id_proces'=>$r->ID_PROCES, '_type'=>$_type), array('title'=>"Edytuj pytanie", 'ico'=>'edit', 'onclick'=>$js_onclick));
			}
			$out .=  "<code>[".$r->ID."]</code> ";
			{
				$field = "ID_WSKAZNIK";
				if ($this_edit) {
					$out .= '<span class="green">'."Wskaznik: ".'</span>';
					$out .= '<input type="text" name="'.$prefix.$field.'" value="'.$r->ID_WSKAZNIK.'" size="6" />';
					$out .= ' <i class="silver">(id wskaznika lub 0)</i>';
				} else {
					if ($r->ID_WSKAZNIK > 0) {
						$out .= '<span class="green">'."Wskaznik: ".$r->ID_WSKAZNIK.".".'</span>';
					}
				}
			}
			$out .=  " Tresc pytania (" . $_type . "): ";
			$field = "PYTANIE";
			//echo'<input type="text" name="'."edit_".$field.'" value="'.$r->$field.'" size="130" maxlength="255" />';
			$out .=  '<br />'.'<textarea name="'.$prefix.$field.'" cols="90" rows="3"' . $attr_readonly . '>'.htmlspecialchars($r->$field).'</textarea>';
			for ($i = 0; $i < 5; $i++) {
				$field = "ODP_".$i;
				if (!$this_edit && empty($r->$field)) continue;
				$out .= '<p style="margin:0 2px;">';
					$out .=  "".($i + 1).". odpowiedz: ";
					$out .= '<input type="text" name="'.$prefix.$field.'" value="'.htmlspecialchars($r->$field).'" size="70" maxlength="100" ' . $attr_readonly . '/>';
					$out .=  " poprawna: ";
					$field = "ODP_".$i."_ODP";
					$out .= '<select name="'.$prefix.$field.'">';
					$options = array("", "TAK", "NIE");
					foreach ($options as $k) {
						$sel = ($r->$field == $k)? ' selected="selected"' : '';
						$out .= '<option value="'.$k.'"'.$sel.'>'.$k.'</option>';
					}
					$out .= '</select>';
				$out .= '</p>';
			}
			if ($this_edit) {
				$sbmt_value = 'Zapisz';
				if ($prefix == 'add_') $sbmt_value = 'Dodaj';
				$out .= '<input type="submit" value="'.$sbmt_value.'" />';
				$out .= '</form>';
			}
			$out .= '</div>';// .box
		}
		return $out;
	}

	$form_sent = false;
	$pytania = ProcesTestyHelper::get_pytania_by_proces_id($proces->ID, $_type);
	$pytania_out = array();
	if (!empty($pytania)) {
		foreach ($pytania as $kPytanieId => $vPytanieObj) {
			$pytania_out[] = this_print_form_pytanie($vPytanieObj, 'edit_'.$kPytanieId.'_', $id_pytanie, $_type);
		}
	}
	// TODO: link dodaj pytanie i 5 odpowiedzi TAK/NIE
	$new = new stdClass();
	foreach (get_object_vars($r) as $key => $val) {
		$new->$key = '';
	}
	$new->ID_PROCES = $proces->ID;
	$new->ID_WSKAZNIK = $id_wskaznik;
	$pytanie_out = this_print_form_pytanie( $new, 'add_', $id_pytanie, $_type );
	if ($pytanie_out === true) {
		$form_sent = true;
	}
	$pytania_out[] = $pytanie_out;

	if ($form_sent) {
		echo App::link( "odswiez strone", array('task'=>App::get_task(), 'id_proces'=>81) );
		return;
	}

	// pytania
	echo'<h3>'."Pytania testowe:".'</h3>';
	if (empty($pytania)) {
		echo '<p style="color:red">' . "Brak pytań typu: " . $types_allowed[$_type] . '</p>';
	}
	foreach ($pytania_out as $out) {
		echo $out;
	}
}


function tree_callback__show_test_item_from_CRM_PROCES(&$r, &$tree) {
	$cls = array();
	$cls = (!empty($cls))? implode(' ', $cls) : '';
	$tree_test_type = $tree->get_param('TEST_TYPE');
	$changedAfterLastTest = false;
	if ($tree->get_param('show_state') == 'items') {
		$lastTestDate = $tree->get_param('lastTestDate');
		$itemDate = ($r->A_RECORD_UPDATE_DATE)? $r->A_RECORD_UPDATE_DATE : $r->A_RECORD_CREATE_DATE;
		$changedAfterLastTest = ($itemDate > $lastTestDate);
	}

	$outItemClass = '';
	if ($r->TYPE == 'PROCES_INIT') $outItemClass .= ' btn-box-red';
	if ($changedAfterLastTest) $outItemClass .= ' changed-after-last-test';

	$treeItemDesc = '';
	if ($tree->get_param('show_state') == 'items') {
		if ($r->TEST_PYTANIE) {// pytanie ponizej
		} else {// TODO: brak pyta??
			$treeItemDesc = $r->DESC;
		}
	} else {// TODO: brak pyta??
		$treeItemDesc = $r->DESC;
	}
	//if ($tree->get_param('rozwin_opis') && $r->OPIS) echo' <span class="more-desc">'.$r->OPIS.'</span>';

	$pytaniaOut = array();
	if ($tree->get_param('show_state') == 'items') {
		Lib::loadClass('ProcesTestyHelper');
		$pytaniaRaw = ProcesTestyHelper::get_pytania_by_proces_id($r->ID, $tree_test_type);
		if (!empty($pytaniaRaw)) {
			foreach ($pytaniaRaw as $p) {
				$p->otwarte = true;
				$odpowiedziOut = array();
				for ($i = 0; $i < 5; $i++) {
					$odpOut = new stdClass();
					$odpOut->questionFormFldName = "ODP_{$p->ID}";
					$odpOut->questionFldName = "ODP_{$i}";
					if (!empty($p->{$odpOut->questionFldName})) {
						$p->otwarte = false;
						$odpOut->answearFldName = "{$odpOut->questionFormFldName}_ODP_{$i}";
						$odpOut->answearLabel = $p->{$odpOut->questionFldName};
						$odpOut->answears = array('', 'TAK', 'NIE');
						$odpOut->userAnswear = $tree->get_param($odpOut->answearFldName);
						$odpowiedziOut[] = $odpOut;
					}
				}

				if ($p->otwarte) {
					$p->questionFldName = "ODP_{$p->ID}";
					$p->userAnswear = $tree->get_param($odpOut->questionFldName);
				} else {
					$p->odpowiedzi = $odpowiedziOut;
				}

				$pytaniaOut[] = $p;
			}
		}
		if('1'==V::get('DBG_ODP', '', $_GET) && !empty($pytaniaOut)) {
			echo'<pre>';print_r($tree);echo'</pre>';
			echo'<pre>';print_r($pytaniaOut);echo'</pre>';
		}
	}

	?>
	<dl class="<?php echo $cls; ?>">
	<dt>
		<span class="item_id btn-box <?php echo $outItemClass; ?>"><?php echo $r->ID; ?></span>
		<?php if ($changedAfterLastTest) : ?>
			<i class="glyphicon glyphicon-exclamation-sign" style="color:orange;" title="Proces został zmieniony od poprzedniego wykonania testu"></i>
		<?php endif; ?>

		<span class="desc">
			<b><?php echo $treeItemDesc; ?></b>
		</span>
		<?php if (!empty($pytaniaOut)) : ?>
			<?php foreach ($pytaniaOut as $pytanieOut) : ?>
				<div>
					<span class="desc"><?php echo $pytanieOut->PYTANIE; ?></span>
					<?php if ($pytanieOut->otwarte) : ?>
						<textarea class="form-control" name="<?php echo $pytanieOut->questionFldName; ?>" rows="3" cols="60"><?php echo $pytanieOut->fldName; ?></textarea>
					<?php else : ?>
						<div style="padding-left:40px;">
							<?php foreach ($pytanieOut->odpowiedzi as $vOdp) : ?>
								<div class="form-group">
									<select class="form-control input-sm" style="width:100px" name="<?php echo $vOdp->answearFldName; ?>">
										<?php foreach ($vOdp->answears as $answear) : ?>
											<?php $sel = ($vOdp->userAnswear == $answear)? ' selected="selected"' : ''; ?>
											<option value="<?php echo $answear; ?>" <?php echo $sel; ?>><?php echo $answear; ?></option>
										<?php endforeach; ?>
									</select>
									<label style="font-weight:normal;"><?php echo $vOdp->answearLabel; ?></label>
								</div>
							<br>
							<?php endforeach; ?>
						</div>
					<?php endif; ?>
				</div>
			<?php endforeach; ?>
			<div style="padding:6px 40px;">
				<input class="btn btn-default btn-xs" type="submit" name="save" value="Zapisz" />
			</div>
		<?php endif; ?>
	</dt>
	</dl>
	<?php
}


function tree_callback__show_wynik_item_from_CRM_PROCES(&$r, &$tree) {
	$cls = array();
	$cls = (!empty($cls))? ' class="'.implode(' ', $cls).'"' : '';
	echo '<dl'.$cls.'>';
	echo '<dt>';

	$tree_test_type = $tree->get_param('TEST_TYPE');
	$tree_show_state = $tree->get_param('show_state');// 'parents', 'items'

	echo '<span class="item_id btn-box'.(($r->TYPE == 'PROCES_INIT')? ' btn-box-red' : '').'">'.$r->ID.'</span>';

	echo' <span class="desc">';
		echo'<b>'.$r->DESC.'</b>';
	echo'</span>';

	$oceny = array();
	$oceny[0] = '0 - nic';
	$oceny[1] = '1 - slabo';
	$oceny[2] = '2 - prawie dobrze';
	$oceny[3] = '3 - dobrze';

	if ($tree_show_state == 'items') {
		Lib::loadClass('ProcesTestyHelper');
		$pytania = ProcesTestyHelper::get_pytania_by_proces_id($r->ID, $tree_test_type);
		if (!empty($pytania)) {
			foreach ($pytania as $p) {
				echo'<br />';
				echo'<i title="'."ID pytania: ".$p->ID.'">{'.$p->ID.'}</i>';
				echo' <span class="desc">'.$p->PYTANIE.'</span> ';
				// TODO: nazwy pol dla pytan
				$field = "ODP_".$p->ID;
				/**
				 * TODO: pokaz tylko odpowiedz udzielona przez kandydata i czy jest prawidlowa
				 * ODP_{id_pyt}
				 * ODP_{id_pyt}_{id_odp} (TAK/NIE)
				 */
				$selected_values = array();
				$pytanie_otwarte = true;
				$sum_odp_cnt = 0;
				$sum_odp_ok_cnt = 0;
				for ($i = 0; $i < 5; $i++) {
					$odp_field = "ODP_".$i;
					if ($p->$odp_field != '') {// jest odpowiedz do pytania
						$sum_odp_cnt += 1;
						$odp_field_prawidlowa = "ODP_".$i."_ODP";
						$pytanie_otwarte = false;
						$field_odpowiedz = $field."_ODP_".$i;
						$selected_values[$i] = $tree->get_param($field_odpowiedz);
						echo'<br /> - <span class="red">'.$p->$odp_field.'</span>: "'.$tree->get_param($field_odpowiedz).'"';
						if ($tree->get_param($field_odpowiedz) != '' && $p->$odp_field_prawidlowa == $tree->get_param($field_odpowiedz)) {
							$sum_odp_ok_cnt += 1;
							echo' <b class="green">'."OK".'</b>';
						} else {
							echo' <b class="red">'."ZLE".'</b> <i>(prawidlowa odp: '.$p->$odp_field_prawidlowa.')</i>';
						}
					}
				}
				$ocena_post_field_name = "ocena_".$p->ID;
				if (!$pytanie_otwarte) {
					$pyt_wynik = ProcesTestyHelper::ocen_pytanie($p, $selected_values);
					$pyt_ocena = $oceny[$pyt_wynik];
					echo'<input type="hidden" name="'.$ocena_post_field_name.'" value="'.$pyt_wynik.'" />';
					echo'<br /> --- <b class="blue">WYNIK</b>: '.$sum_odp_ok_cnt.' dobrych odpowiedzi z '.$sum_odp_cnt.' = <b class="blue">'.$pyt_ocena.'</b>';
				} else {
					echo'<br />';
					echo'<textarea rows="3" cols="60">'.$tree->get_param($field).'</textarea>';
					echo'<br /> --- <b class="blue">WYNIK</b>: ';
					echo'<select name="'.$ocena_post_field_name.'">';
					foreach ($oceny as $k_ocena => $v_ocena) {
						$sel = ($k_ocena == $tree->get_param("ocena_".$p->ID))? ' selected="selected"' : '';
						echo'<option value="'.$k_ocena.'"'.$sel.'>'.$v_ocena.'</option>';
					}
					echo'</select>';
				}
			}
		}
	}
	echo'</dt>'."\n";
	echo'</dl>'."\n";
}


function task_CRM_TESTY_WYNIKI_CERTYFIKAT() {
	$kandydat_id = V::get('kandydat_id', 0, $_GET, 'int');

	if ($kandydat_id <= 0) {
		echo'<p class="red">'."Wrond user!".'</p>';
		return;
	}

	Lib::loadClass('ProcesTestyHelper');

	$params = array();
	$params['limit'] = V::get('_limit', 100, $_GET, 'int');
	$params['offset'] = V::get('_offset', 0, $_GET, 'int');
	$params['order_by'] = V::get('_order_by', 'ID', $_GET);
	$params['order_dir'] = V::get('_order_dir', 'DESC', $_GET);
	$params['id_tester'] = $kandydat_id;
	$params['proces_name'] = true;
	$params['organizer_name'] = true;
	$params['SHOW_IN_CERT'] = 'TAK';

	// validate params
	if ($params['offset'] < 0) $params['offset'] = 0;

	$lista_cnt = ProcesTestyHelper::get_testy_total( $params );
	if ($lista_cnt <= 0) {
		echo "Brak testów";
		return;
	}
	if ($params['offset'] > $lista_cnt) $params['offset'] = $lista_cnt - ($lista_cnt % $params['limit']);

	$testy_arr = ProcesTestyHelper::get_testy( $params );
	$testy_zakonczone = array();
	foreach ($testy_arr as $test) {
		if ($test->A_STATUS == 'OFF_HARD' && $test->TEST_END > '0000-00-00') {// $test->OCENA > 0
			$testy_zakonczone[] = $test;
		}
	}

	$kand = reset($testy_zakonczone);
	$kandydat_name = $kand->Kandydat_Name;
	$kandydat_stanowiska = array();
	foreach ($testy_zakonczone as $kand) {
		$kandydat_stanowiska [$kand->Stanowisko] = true;
	}
	$kandydat_stanowiska = implode(', ', array_keys($kandydat_stanowiska));

	echo'<p style="text-align:center">' . "Załącznik nr 1 do umowy na sfinansowanie szkoleń pracownika" . '</p>';
	//echo'<p style="text-align:right">' . "Gda??sk dnia " . date("Y-m-d") . '</p>';
	//echo'<p style="text-align:right;margin:50px 0;">';
	//	echo "Biall-Net Sp. z o.o." . '<br />';
	//	echo "Otomin, ul. S??oneczna 43" . '<br />';
	//	echo "80-174 Gda??sk" . '<br />';
	//echo'</p>';
	echo '<br />';
	echo'<h1 style="text-align:center;">' . "Certyfikat ukończenia szkolenia" . '</h1>';
	echo'<p>' . "Niniejszym zaświadcza się, że Pan/Pani " . $kandydat_name . " ukończył/a z wynikiem pozytywnym szkolenie w zakresie " . $kandydat_stanowiska . "." . '</p>';
	echo'<br />';
	//echo'<p>' . "Uczestnik uzyska?? nast??puj??ce wyniki:" . '</p>';
	echo'<style type="text/css">'."
.tbl-cert {margin:0 auto; width:98%;}
.tbl-cert td {font-size:small;}
	".'</style>';
	echo'<table cellspacing="0" cellpadding="2" border="1" class="tbl-cert">';
	echo '<thead>';
	echo '<tr>';
		echo '<td colspan="3">' . "Tytuł Szkolenia" . '</td>';
		echo '<td rowspan="2">' . "Data szkolenia" . '</td>';
		echo '<td rowspan="2">' . "Organizator Szkolenia" . '</td>';
		echo '<td rowspan="2">' . "Miejsce szkolenia" . '</td>';
		echo '<td rowspan="2">' . "Data testu" . '</td>';// "Data szkolenia" - drugi raz?
		echo '<td rowspan="2">' . "Czas szkolenia" . '</td>';
		echo '<td rowspan="2">' . "Ocena" . '</td>';
		echo '<td rowspan="2">' . "Całkowity koszt udziału jednego uczestnika w szkoleniu" . '</td>';
		echo '<td rowspan="2">' . "Kwota udzielonego rabatu" . '</td>';
		echo '<td rowspan="2">' . "Uwagi" . '</td>';
	echo '</tr>';
	echo '<tr>';
		echo '<td>' . "Numer procesu" . '</td>';
		echo '<td>' . "Nazwa procesu" . '</td>';
		echo '<td>' . "Obszar działania" . '</td>';
	echo '</tr>';
	echo '</thead>';
	echo '<tbody>';
	foreach ($testy_zakonczone as $test) {
		echo'<tr>';
			echo'<td>' . $test->ID_PROCES_INIT . '</td>';
			echo'<td>' . $test->Proces_Name . '</td>';
			echo'<td>' . $test->Stanowisko . '</td>';
			echo'<td>' . '<nobr>' . substr($test->TEST_INIT, 0, 10) . '</nobr>' . '</td>';
			echo'<td>' . $test->Organizer . '</td>';// ID_ORGANIZER "Organizator Szkolenia" - (uzupe??niane przy ocenianiu-select )
			echo'<td>' . $test->TEST_PLACE . '</td>';// TEST_PLACE "Miejsce szkolenia" - uzupe??niane przy ocenianiu - select z zasob??w+devices/telbox)
			echo'<td>' . '<nobr>' . substr($test->TEST_END, 0, 10) . '</nobr>' . '</td>';
			echo'<td>' . '...' . '</td>';// TEST_TIME "Czas szkolenia" - (uzupe??nia??  przy przy ocenianiu )
			echo'<td>' . $test->OCENA . '</td>';
			echo'<td>' . number_format($test->COST, 2, ',', ' ') . " zł" . '</td>';// COST "Ca??kowity koszt udzia??u jednego uczestnika w szkoleniu" - (uzupe??niane przy ocenianiu)
			echo'<td>' . number_format($test->DISCOUNT, 2, ',', ' ') . " zł" . '</td>';
			echo'<td>' . $test->UWAGI . '</td>';
		echo'</tr>';
	}
	echo '</tbody>';
	echo '</table>';
	//echo '<p style="text-align:right;margin:100px 0 0 0;">' . ".............................................................." . '<br />' . "(piecz???? firmowa i podpis prezesa)" . '</p>';
	echo '<table cellspacing="0" cellpadding="0" border="0" style="margin:30px 0 0 30px;">';
	echo '<tr>';
		echo '<td style="vertical-align:top">';
			echo "Data:";
		echo '</td>';
		echo '<td style="width:200px;padding:0 30px;vertical-align:bottom; text-align:center;">';
			echo '<br /><br /><br /><br />';
			echo '<p style="border-top:1px dotted #000; font-style:italic">' . "Pracodawca" . '</p>';
		echo '</td>';
		echo '<td style="width:200px;padding:0 30px;vertical-align:bottom; text-align:center;">';
			echo '<br /><br /><br /><br />';
			echo '<p style="border-top:1px dotted #000; font-style:italic">' . "Pracownik" . '</p>';
		echo '</td>';
	echo '</tr>';
	echo '</table>';
}


/**
 * @param $_GET['id']
 */
function task_CRM_TESTY_WYNIKI_EDIT() {
	$test_id = V::get('test_id', 0, $_GET, 'int');

	echo '<h1>';
		echo App::link("Wyniki", array('task'=>"CRM_TESTY_WYNIKI"));
		echo " &raquo; ";
		echo App::link("Edycja [" . $test_id . "]", array('task'=>"CRM_TESTY_WYNIKI_EDIT", 'test_id'=>$test_id));
	echo '</h1>';

	if (!User::hasAccess('testy_wyniki_edit')) {
		echo '<p style="color:red">' . "Error - brak uprawnień!" . '</p>';
		echo App::link("wróć", array('task'=>'CRM_TESTY_WYNIKI'));
		return;
	}

	if ($test_id <= 0) {
		echo '<p style="color:red">' . "Error - błędny numer testu!" . '</p>';
		echo App::link("wróć", array('task'=>'CRM_TESTY_WYNIKI'));
		return;
	}

	$test_obj = DB::get_by_id( 'CRM_TESTY', $test_id );
	if (!$test_obj) {
		echo '<p style="color:red">' . "Error - test " . $test_id . " nie istnieje!" . '</p>';
		echo App::link("wróć", array('task'=>'CRM_TESTY_WYNIKI'));
		return;
	}

	// fetch POST values - TODO: use $tbl_conf
	$test_obj->UWAGI = V::get('UWAGI', $test_obj->UWAGI, $_POST);
	$test_obj->COST = V::get('COST', $test_obj->COST, $_POST, 'double');
	$test_obj->ID_ORGANIZER = V::get('ID_ORGANIZER', $test_obj->ID_ORGANIZER, $_POST);
	$test_obj->TEST_PLACE = V::get('TEST_PLACE', $test_obj->TEST_PLACE, $_POST);
	$test_obj->SHOW_IN_CERT = V::get('SHOW_IN_CERT', $test_obj->SHOW_IN_CERT, $_POST);

	Column::init('CRM_TESTY', true);// TODO: mv to procesy5.php:134 without force=true

	$tbl = 'CRM_TESTY';

	$tbl_conf = Column::getInstance($tbl);
	if (!$tbl_conf) {
		echo'<p class="red">'."Brak konfiguracji dla ".$tbl."!".'</p>';
		return;
	}
	$visible_cols = $tbl_conf->getVisibleFieldList();

	echo '<form action="" method="post">';
		echo'<input type="hidden" name="task" value="'."CRM_TESTY_WYNIKI_EDIT".'" />';
		echo'<input type="hidden" name="test_id" value="' . $test_obj->ID . '" />';
		echo'<input type="hidden" name="function_init" value="'."fun_CRM_TEST_EDIT".'" />';
		echo'<input type="hidden" name="subtask" value="'."EDIT".'" />';
		$t = 1;
		echo '<table cellspacing="0" cellpadding="0" class="tbl-view" border="1">';
		foreach ($visible_cols as $field_id => $field_name) {
			$v_field = array();
			$v_field['label'] = $tbl_conf->desc($field_name);
			if (!$v_field['label']) $v_field['label'] = $field_name;
			$v_field['cnt'] = '';

			if ($field_name == 'ID') {
				$v_field['cnt'] .= '<input type="hidden" name="test_id" value="' . $test_obj->ID . '" />';
				$v_field['cnt'] .= $test_obj->ID;
				$v_field['label'] = App::link("hist", array('task'=>"CRM_TESTY_WYNIKI_HIST", 'test_id'=>$test_obj->ID), array('ico'=>'history')) . " " . $v_field['label'];
			} else {
				if ($tbl_conf->allowWrite($field_name)) {
					$v_field['cnt'] .= App::field( '' . $field_name, $tbl_conf->type($field_name), $test_obj->$field_name, array('class'=>'i') );
				} else {
					$v_field['cnt'] .= $test_obj->$field_name;
				}
			}
			echo '<tr class="row-' . ($t = 1 - $t) . '">';
				echo '<th>' . $v_field['label'] . '</th>';
				echo '<td>' . $v_field['cnt'] . '</td>';
			echo '</tr>';
		}
		echo '<tr>';
			echo '<td colspan="2">';
				echo '<input type="submit" value="' . "zapisz" . '" />';
			echo '</td>';
		echo '</tr>';
		echo '</table>';
	echo '</form>';
}


/**
 * @param $_GET['id']
 */
function task_CRM_TESTY_WYNIKI_HIST() {
	$test_id = V::get('test_id', 0, $_GET, 'int');

	echo '<h1>';
		echo App::link("Wyniki", array('task'=>"CRM_TESTY_WYNIKI"));
		echo " &raquo; ";
		echo App::link("Edycja [" . $test_id . "]", array('task'=>"CRM_TESTY_WYNIKI_EDIT", 'test_id'=>$test_id));
		echo " &raquo; ";
		echo App::link("Historia [" . $test_id . "]", array('task'=>"CRM_TESTY_WYNIKI_HIST", 'test_id'=>$test_id));
	echo '</h1>';

	if ($test_id <= 0) {
		echo '<p style="color:red">' . "Error - błędny numer testu!" . '</p>';
		echo App::link("wróć", array('task'=>'CRM_TESTY_WYNIKI'));
		return;
	}


	$hist = array();
	$sql = "select * from `CRM_TESTY_HIST` where `ID_USERS2`='" . $test_id . "' order by ID DESC ";
	$res = DB::query( $sql );
	while ($r = DB::fetch( $res )) {
		$hist[] = $r;
	}

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

	$cols = array();
	foreach (get_object_vars(reset($hist)) as $field_name => $v) {
		$cols[] = $field_name;
	}
	echo '<table class="tbl-view" cellspacing="0" cellpadding="0" border="1">';
	echo '<thead>';
		echo '<tr>';
			foreach ($cols as $field_name) {
				echo '<th>' . str_replace('_' , ' ', $field_name) . '</th>';
			}
		echo '</tr>';
	echo '</thead>';
	echo '<tbody>';
	$t = 0;
	foreach ($hist as $r) {
		echo '<tr class="row-' . ($t = 1 - $t) . '">';
		foreach ($cols as $field_name) {
			$cell_out = $r->$field_name;
			if ($r->$field_name == 'N/S;') {
				$cell_out = '<em style="color:#666">' . $cell_out . '</em>';
			}
			echo '<td>' . $cell_out . '</td>';
		}
		echo '</tr>';
	}
	echo '</tbody>';
	echo '</table>';

}


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

/* $_GET
	[p] => Array(
            [0] => 2535
            [1] => 83
            [2] => 975
            [3] => 2495
 */

	$order_list = V::get('p', null, $_GET, 'array');

	$zmieniono_cnt = 0;
	$zmieniono_err = 0;
	if (!empty($order_list)) {
		Lib::loadClass('ProcesHelper');
		$proces_list = ProcesHelper::get_procesy_init_list_order();// array ID => TEST_SORT_PRIO
		// order by p.`TEST_SORT_PRIO` DESC, p.`ID` ASC

		if (count($order_list) == count($proces_list)) {
			$order_list = array_reverse($order_list);
			$order_new_list = array_flip($order_list);

			$db = DB::getDB();
			foreach ($proces_list as $k_proces_id => $v_sort_id) {
				if ($order_list[$v_sort_id] != $k_proces_id) {
					$sql_obj = new stdClass();
					$sql_obj->ID = $k_proces_id;
					$sql_obj->TEST_SORT_PRIO = $order_new_list[$k_proces_id];
					$affected = $db->UPDATE_OBJ('CRM_PROCES', $sql_obj);
					if ($affected > 0) {
						$zmieniono_cnt++;
					} else {
						$zmieniono_err++;
					}
				}
			}
		} else {
			//echo 'Error count';
		}
	}

	if ($zmieniono_cnt > 0) {
		App::add_msg("Kolejność {$zmieniono_cnt} procesów została zmieniona");
	}
	if ($zmieniono_err > 0) {
		App::add_error("Wystąpiły błędy przy zmianie kolejności dla {$zmieniono_err} procesów");
	}
	if ($zmieniono_cnt == 0 && $zmieniono_err == 0) {
		App::add_msg("Kolejność nie została zmieniona");
	}
	App::redirect($redirect, $msg);
}


function task_TEST_SORT() {

	Lib::loadClass('ProcesHelper');

	$proces_id = V::get('_proces_id', 0, $_GET, 'int');
	if ($proces_id > 0) {
		$allowed_dir = array('up', 'dw');
		$dir = V::get('_dir', '', $_GET);
		if (in_array($dir, $allowed_dir)) {
			echo '<p>' . "Przenoszenie procesu {$proces_id} w " . (($dir == 'up')? "górę" : "dół");
			$ret = ProcesHelper::proces_init_move($proces_id, $dir);
			if ($ret > 0) {
				echo ' - ok';
				echo ' - ' . App::link('powtórz', array('task'=>'TEST_SORT', '_proces_id'=>$proces_id, '_dir'=>$dir), array('class'=>'btn-clean', 'title'=>'powtórz zmianę kolejności'));
			} else {
				echo ' - error';
			}
			echo '</p>';
		}
	}

	$proces_list = ProcesHelper::get_procesy_init_list();
	$goto_list = ProcesHelper::get_goto_list(array('return_by'=>'dest'));

	$cols = array();
	$cols['ID'] = "ID";
	$cols['DESC'] = "DESC";
	//$cols['TEST_SORT_PRIO'] = "Kolejno????";

	?>
	<style type="text/css">
.tbl-view .selected td {background:#FCFFCE;}
.tbl-view tr { background:#fff; }
.tbl-view tr:nth-child(even) { background:#F3F3F3; }

#sortableProcesList tr {cursor:pointer;}
#sortableProcesList td {color:#000;}
#sortableProcesList .ui-state-highlight { height:1.1em; line-height:1em; }
#sortableProcesList .sortableProcesList-title {display:block; width:360px; height:3em; line-height:3em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
#sortableProcesList .sortableProcesList-goto {display:block; height:3em; overflow:hidden;}

	</style>
	<script type="text/javascript" src="stuff/jquery-ui.custom.min.js"></script>
	<script type="text/javascript">
jQuery(document).ready(function(){
	jQuery('#sortableProcesList').sortable({
		placeholder: 'ui-state-highlight',
		axis: 'y'
	});
});

function fun_TEST_SORT_SAVE() {
	var sorted_list=jQuery('#sortableProcesList').sortable('serialize', {attribute: 'id', key: 'p[]'});
	window.location.href='?task=TEST_SORT&function_init=fun_TEST_SORT_SAVE&' + sorted_list;
	return false;
}
	</script>
	<table cellspacing="0" cellpadding="0" border="1" class="tbl-view">
	<thead>
		<tr>
			<th>Nr</th>
			<th style="width:360px">Opis</th>
			<th>Kolejność
				<?php echo App::link('save', array('task'=>'TEST_SORT', 'function_init'=>'fun_TEST_SORT_SAVE'), array('ico'=>'save', 'title'=>"Zapisz kolejność", 'onclick'=>"return fun_TEST_SORT_SAVE();")); ?>
			</th>
			<th style="width:30%;">GOTO</th>
			<th></th>
		</tr>
	</thead>
	<tbody id="sortableProcesList">
	<?php
	foreach ($proces_list as $v_proces) {
		// class="(($proces_id == $v_proces->ID)? ' selected' : '')"
		echo '<tr id="p_' . $v_proces->ID . '" class="ui-state-default">';
		foreach ($cols as $k_cell => $v_label) {
			$value = $v_proces->{$k_cell};
			if ('DESC' == $k_cell) {
				$value = '<span class="sortableProcesList-title" title="' . htmlspecialchars($value) . '">' . $value . '</span>';
			}
			echo '<td>' . $value . '</td>';
		}
		echo '<td>';
			echo App::link('^', array('task'=>'TEST_SORT', '_proces_id'=>$v_proces->ID, '_dir'=>'up'), array('class'=>'btn-clean', 'title'=>'w górę'));
			echo ' ';
			echo App::link('v', array('task'=>'TEST_SORT', '_proces_id'=>$v_proces->ID, '_dir'=>'dw'), array('class'=>'btn-clean', 'title'=>'w dół'));
		echo '</td>';
		echo '<td>';// GOTO
			echo '<div class="sortableProcesList-goto">';
				if (array_key_exists($v_proces->ID, $goto_list)) {
					foreach ($goto_list[$v_proces->ID] as $k_id => $v_goto) {
						$title = "Krok {$v_goto->ID} {$v_goto->IF_TRUE_GOTO_FLAG} {$v_goto->IF_TRUE_GOTO}";
						echo '<span class="btn-box" style="font-family:monospace" title="' . $title . '">' . ProcesHelper::proces_flag($v_goto->ID, $v_goto->IF_TRUE_GOTO, $v_goto->IF_TRUE_GOTO_FLAG) . '</span>';
					}
				}
			echo '</div>';
		echo '</td>';
		echo '<td>';
			$path_arr=explode('/', $v_proces->path);
			foreach($path_arr as $path) {
				$col_temp_r=dechex(rand(0,25)*10);
				$col_temp_g=dechex(rand(0,25)*10);
				$col_temp_b=dechex(rand(0,25)*10);
				if(empty($color[$path])) $color[$path]="color='#".(strlen($col_temp_r)==1 ? "0".$col_temp_r : $col_temp_r ).(strlen($col_temp_g)==1 ? "0".$col_temp_g : $col_temp_g ).(strlen($col_temp_b)==1 ? "0".$col_temp_b : $col_temp_b );
				echo " <font color=".$color[$path].">".$path."</font>(".$v_proces->SORT_PRIO.")";
			}

			if($path_arr[count($path_arr)-2]==$path_last['ID']) { //ostatni parent jest taki sam, wiec sa w jednym miejscu
//				if($v_proces->TEST_SORT_PRIO>$path_last['TEST_SORT_PRIO']) echo "wieksz. TSP niz ostatni";
//				if($v_proces->TEST_SORT_PRIO<=$path_last['TEST_SORT_PRIO']) echo "mniejsz. TSP niz ostatni";
//				if($v_proces->SORT_PRIO>$path_last['SORT_PRIO']) echo "OK ? wieksz. sort niz ostatni";
				if($v_proces->SORT_PRIO<$path_last['SORT_PRIO']) echo "&nbsp; Błąd kolejności pod kątem ustalenia w drzewie procesów";
			}

			$path_last['ID']=$path_arr[count($path_arr)-2];
			$path_last['TEST_SORT_PRIO']=$v_proces->TEST_SORT_PRIO;
			$path_last['SORT_PRIO']=$v_proces->SORT_PRIO;
		//	echo $path_last['ID']."==?".$path_arr[count($path_arr)-2]." / ".$path_last['TEST_SORT_PRIO']." ".$path_last['SORT_PRIO'];

		echo '</td>';
		echo '</tr>';
	}
	echo '</tbody>';
	echo '</table>';
}
