فهرست منبع

mv TableAjax send file content to branch feature-files-proxy, prepare to merge with ahmes

Piotr Labudda 11 سال پیش
والد
کامیت
86bfc2a163
5فایلهای تغییر یافته به همراه653 افزوده شده و 180 حذف شده
  1. 0 8
      SE/.htaccess
  2. 0 90
      SE/index-file.php
  3. 3 3
      SE/se-lib/PokazOfertyView.php
  4. 15 79
      SE/se-lib/TableAjax.php
  5. 635 0
      SE/superedit-AHMES_REKLAMACJE.php

+ 0 - 8
SE/.htaccess

@@ -1,8 +0,0 @@
-<IfModule mod_rewrite.c>
-RewriteEngine On
-RewriteBase /
-RewriteRule ^index\.php$ - [L]
-RewriteCond %{REQUEST_FILENAME} !-f
-RewriteCond %{REQUEST_FILENAME} !-d
-RewriteRule ^PLIKI/([0-9-]+)/([0-9-]+)/(.*)$ /SE/se-dev-pl-rsync/index-file.php?zasobID=$1&id=$2&file=$3 [L]
-</IfModule>

+ 0 - 90
SE/index-file.php

@@ -1,90 +0,0 @@
-<?php
-
-define('DS', DIRECTORY_SEPARATOR);
-define('APP_PATH_ROOT', dirname(__FILE__));
-define('APP_PATH_LIB', APP_PATH_ROOT . '/se-lib');
-define('APP_PATH_WWW', APP_PATH_ROOT);
-define('APP_PATH_CONFIG', APP_PATH_ROOT . DS . 'config');
-
-session_start();
-
-date_default_timezone_set('Europe/Warsaw');// PHP 5 >= 5.1.0 required by date functions
-
-error_reporting(1);
-ini_set('error_reporting', 1);
-ini_set('display_startup_errors','1'); 
-//display_startup_errors(0);
-
-#TEST $_SESSION['DEBUG'] = 3;// TODO: TEST
-if (!isset($_SESSION['DEBUG'])) $_SESSION['DEBUG'] = 0;// set default value
-
-
-if (file_exists(APP_PATH_ROOT . "/config/.config_{$_SERVER['SERVER_NAME']}.php")) {
-	require APP_PATH_ROOT . "/config/.config_{$_SERVER['SERVER_NAME']}.php";
-}
-
-if (file_exists(APP_PATH_ROOT . "/.config.php")) include APP_PATH_ROOT . "/.config.php";
-
-
-require_once APP_PATH_ROOT . "/superedit-SEF.php";
-SEF('DEBUG_S');
-
-require_once APP_PATH_LIB . '/' . 'Lib.php';
-Lib::loadClass('V');
-Lib::loadClass('DB');
-Lib::loadClass('User');
-Lib::loadClass('S');
-Lib::loadClass('Http');
-Lib::loadClass('HttpException');
-
-if (!User::logged()) {
-	Http::sendHeaderByCode(401);
-	exit;
-}
-
-/* example:
-    [zasobID] => 636
-    [id] => 2773
-    [file] => 2014-07-11_wizytowki_michal_zaleski_wzor_bn2.bcard/Screen Shot 2014-07-11 at 15.58.15.png
-*/
-
-$zasobID = V::get('zasobID', 0, $_GET, 'int');
-$recordID = V::get('id', 0, $_GET, 'int');
-$fileName = V::get('file', '', $_GET);
-
-if (!$zasobID || !$recordID || empty($fileName)) {
-	Http::sendHeaderByCode(406);
-	exit;
-}
-if (false !== strpos($fileName, '../')) {
-	Http::sendHeaderByCode(403);
-	die('..');
-}
-
-$userAcl = User::getAcl();
-$tblAcl = $userAcl->getTableAcl($zasobID);
-
-if (!$tblAcl->isInitialized()) {
-	Http::sendHeaderByCode(404);
-	die("Brak konfiguracji dla ".$tblAcl->getName()."!");
-}
-
-Lib::loadClass('TableAjax');
-if (!class_exists('TableAjax')) {
-	Http::sendHeaderByCode(404);
-	die('Error: cls not exists TableAjax');
-}
-
-$tblObj = new TableAjax($tblAcl);
-try {
-	$tblObj->sendFileContent($recordID, $fileName);
-}
-catch (HttpException $e) {
-	Http::sendHeaderByCode($e->getCode());
-	header('Content-Type: text/html; charset=utf-8');
-	echo $e->getMessage();
-}
-catch (Exception $e) {
-	header('Content-Type: text/html; charset=utf-8');
-	echo 'Error ' . $e->getCode() . ':' . $e->getMessage();
-}

+ 3 - 3
SE/se-lib/PokazOfertyView.php

@@ -620,16 +620,16 @@ function show_opcje(cell_id, service){
 function select_option(n){
 	n=jQuery(n);
 
-	console.log('n.data(p_service):', n.data('p_service'), 'n.val', n.val());
+	//console.log('n.data(p_service):', n.data('p_service'), 'n.val', n.val());
 	var p_service = n.data('p_service'), opcja_id = n.val();
 	if ('OPCJA_' == p_service.substr(0, 6) && opcja_id > 0) {
 		var parentTr = n.parent().parent(),
 			service = p_service.substr(6);
 
 		// TODO: hide/show if checked or not
-		console.log('TODO: n.prop(checked): ', n.prop('checked'));
+		//console.log('TODO: n.prop(checked): ', n.prop('checked'));
 		if (n.prop('checked')) {
-			console.log('TODO: p_service: ', p_service, 'n.val()', n.val(), 'service to load:', service, 'parentTr', parentTr);
+			//console.log('TODO: p_service: ', p_service, 'n.val()', n.val(), 'service to load:', service, 'parentTr', parentTr);
 			var tbody_opcje=jQuery('#oferty-opcje-service-' + service).find('tr');
 			if (tbody_opcje.length > 0) {
 				for (var i = 0; i < tbody_opcje.length; i++) {

+ 15 - 79
SE/se-lib/TableAjax.php

@@ -334,7 +334,7 @@ class TableAjax extends ViewAjax {
 .AjaxTable td, .AjaxTableEdit td,
 .AjaxTable th, .AjaxTableEdit th { border-color:#999; }
 
-/*  */
+/* cell A_STATUS */
 .AjaxTable .cell-A_STATUS-NORMAL { background:#aeffae; color:#000; text-align:center; }
 .AjaxTable .cell-A_STATUS-WAITING { background:#ffd2ff; color:#000; text-align:center; }
 .AjaxTable .cell-A_STATUS-MONITOR { background:#cccaff; color:#000; text-align:center; }
@@ -343,6 +343,15 @@ class TableAjax extends ViewAjax {
 .AjaxTable .cell-A_STATUS-OFF_SOFT { background:#fce3b7; color:#808080; text-align:center; }
 .AjaxTable .cell-A_STATUS-OFF_HARD { background:#eee; color:#808080; text-align:center; }
 
+/* cell Status */
+.AjaxTable .cell-Status-U  { background:rgb(0,176,80); color:#000; text-align:center; }
+.AjaxTable .cell-Status-NU { background:#f00; color:#000; text-align:center; }
+.AjaxTable .cell-Status-P  { background:rgb(112,48,160); color:#000; text-align:center; }
+.AjaxTable .cell-Status-PT { background:rgb(127,127,127); color:#000; text-align:center; }
+.AjaxTable .cell-Status-O  { background:rgb(0,176,240); color:#000; text-align:center; }
+.AjaxTable .cell-Status-DZ { background:rgb(0,112,192); color:#000; text-align:center; }
+.AjaxTable .cell-Status-Z  {}
+
 /* map */
 .AjaxTable .cell-mapfld { cursor:pointer; }
 .AjaxTable .cell-mapfld:hover { opacity:1; }
@@ -3794,7 +3803,7 @@ jQuery(document).ready(function(){
 		$files = $uploader->getFilesFromFolder($mainFolder, false, true);
 		$localPath = $uploader->getLocalPath();
 		$folderWeb = $uploader->getFolderWeb();
-		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder, $record->ID);
+		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder);
 		echo json_encode($jsonFiles);
 		exit;
 	}
@@ -3868,12 +3877,12 @@ jQuery(document).ready(function(){
 		$files = $uploader->getFilesFromFolder($mainFolder, false, true);
 		$localPath = $uploader->getLocalPath();
 		$folderWeb = $uploader->getFolderWeb();
-		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder, $record->ID);
+		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder);
 		echo json_encode($jsonFiles);
 		exit;
 	}
 
-	public function convertFileListToJson($files, $folderWeb, $localPath, $mainFolder, $recordID) {
+	public function convertFileListToJson($files, $folderWeb, $localPath, $mainFolder) {
 		sort($files);
 		$jsonFiles = array();
 		foreach ($files as $vFilePath) {
@@ -3890,7 +3899,7 @@ jQuery(document).ready(function(){
 			}
 			$file->type = '';
 			$file->created = date("Y-m-d H:i:s", filectime($vFilePath));
-			$file->web = "PLIKI/{$this->_zasobID}/{$recordID}/{$file->name}";
+			$file->web = str_replace($localPath, $folderWeb, $vFilePath);
 			$jsonFiles[] = $file;
 		}
 		return $jsonFiles;
@@ -4002,7 +4011,7 @@ jQuery(document).ready(function(){
 		}
 		$localPath = $uploader->getLocalPath();
 		$folderWeb = $uploader->getFolderWeb();
-		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder, $record->ID);
+		$jsonFiles = $this->convertFileListToJson($files, $folderWeb, $localPath, $mainFolder);
 		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">jsonFiles (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($jsonFiles);echo'</pre>'; }
 
 		$folderSkanyConf = FoldersConfig::getAll('SCANS_COLUMN');
@@ -4854,77 +4863,4 @@ jQuery(document).ready(function(){
 		return $response;
 	}
 
-	public function sendFileContent($id, $fileName) {
-		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
-
-		$dbID = $this->_acl->getDB();
-		$db = DB::getDB($dbID);
-		if (!$db) {
-			throw new HttpException('No DB', 406);
-		}
-
-		$record = $this->_dataSource->getItem($id);
-		if (!$record) {
-			throw new HttpException("No item ID({$rowID})", 404);
-		}
-
-		if (!$this->_acl->canReadRecord($record)) {// TODO: Write, Super Write?
-			throw new HttpException("Brak dostępu do rekordu", 406);
-		}
-
-		$tblName = $this->_acl->getName();
-		$confTblName = "{$tblName}_COLUMN";
-		Lib::loadClass('FoldersConfig');
-		$folderConfAll = FoldersConfig::getRawData();
-		if (!FoldersConfig::hasConfig($confTblName)) {
-			throw new HttpException("Brak danych konfiguracyjnych", 404);
-		}
-
-		$folderConf = FoldersConfig::getAll($confTblName);
-		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$folderConf (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($folderConf);echo'</pre>'; }
-
-		Lib::loadClass('FileUploader');
-		$uploader = new FileUploader($confTblName, $record);
-		$errMsg = '';
-		if (!$uploader->setConfig($folderConf, $errMsg)) {
-			throw new HttpException("Błąd danych konfiguracyjnych ({$tblName})\n". $errMsg, 404);
-		}
-		$uploader->findFolder();
-		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">uploader (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($uploader);echo'</pre>'; }
-
-		$mainFolder = $uploader->getDestFolder();
-		if($DBG){ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">mainFolder (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($mainFolder);echo'</pre>'; }
-
-		$localPath = $uploader->getLocalPath();
-		$filePath = "{$localPath}/{$mainFolder}/{$fileName}";
-		if (!file_exists($filePath)) {
-			throw new HttpException("Plik nie istnieje", 404);
-		}
-
-		if (function_exists('http_send_file')) {
-			http_send_file($filePath);
-		} else {
-			header('Content-Description: File Transfer');
-			header('Content-Type: application/octet-stream');
-			header('Content-Disposition: attachment; filename='.basename($filePath));
-			header('Content-Transfer-Encoding: binary');
-			header('Expires: 0');
-			header('Cache-Control: must-revalidate');
-			header('Pragma: public');
-			header('Content-Length: ' . filesize($filePath));
-
-			set_time_limit(0);
-			$filePointer = @fopen($filePath, "rb");
-			if (!$filePointer) {
-				throw new HttpException('Problem z odczytem pliku', 500);
-			}
-			while (!feof($filePointer)) {
-				print(@fread($filePointer, 1024*8));
-				ob_flush();
-				flush();
-			}
-			fclose($filePointer);
-		}
-	}
-
 }

+ 635 - 0
SE/superedit-AHMES_REKLAMACJE.php

@@ -0,0 +1,635 @@
+<?php
+
+/**
+ * @param $_GET['task']
+ * @param $_GET['id_koresp']
+ * @param $_GET['id_problem']
+ * 
+ * if $_GET['task'] == 'create_problem'
+ *   @require $_GET['id_koresp']
+ * 
+ * if $_GET['task'] == 'create_koresp_out'
+ *   @require $_GET['id_problem']
+ * 
+ * @requires TYPESPECIALS:
+ *		1613 TYPESPECIALS Powiązania tabel
+ *			6703 TYPESPECIAL id koresp
+ *				6704 (ALIAS DO 668)PARAM_OUT {ID}: {K_OD_KOGO} {K_TYP_KORESP} {K_TYP_RODZAJ}
+ *					6705 (ALIAS DO 668) DANE ID
+ *					6706 (ALIAS DO 654) DANE K_OD_KOGO
+ *					6707 (ALIAS DO 660) DANE K_TYP_KORESP
+ *					6708 (ALIAS DO 643) DANE K_TYP_RODZAJ
+ *					6709 (ALIAS DO 6691) PARAM_IN Problems.ID_KORESP_IN
+ *					6710 (ALIAS DO 6692) PARAM_IN Problems.ID_KORESP_OUT
+ *
+ *			6699 TYPESPECIAL Problems wyślij koresp.
+ *				6700 PARAM_OUT Wyślij koresp.
+ *					6701 (ALIAS DO 4020) DANE ID_PROBLEM
+ *					6702 (ALIAS DO 6693) PARAM_IN ADD_KORESP_OUT_LINK in Problems
+ *
+ *			6695 TYPESPECIAL Koresp. dodaj problem link
+ *				6696 PARAM_OUT Dodaj problem
+ *					6697 (ALIAS DO 668) DANE ID_KORESP
+ *					6698 (ALIAS DO 6694) PARAM_IN ADD_PROBLEM_LINK in Koresp
+ * 
+ */
+function AHMES_REKLAMACJE() {
+	Lib::loadClass('ProcesHelper');
+	$tblProblemsId = ProcesHelper::getZasobTableID('PROBLEMS');
+	$tblKorespId   = ProcesHelper::getZasobTableID('IN7_DZIENNIK_KORESP');
+
+	Lib::loadClass('ProcesHelper');
+
+	$zasobObj = ProcesHelper::getZasobTableInfo($tblProblemsId);
+	if (!$zasobObj) {
+		echo '<div class="alert alert-error">' . "Zasob TABELA ID={$tblProblemsId} nie istnieje" . '</div>';
+		//echo UserActivity::showSimpleList();
+		return;
+	}
+
+	$korespObj = ProcesHelper::getZasobTableInfo($tblKorespId);
+	if (!$korespObj) {
+		echo '<div class="alert alert-error">' . "Zasob TABELA ID={$tblKorespId} nie istnieje" . '</div>';
+		//echo UserActivity::showSimpleList();
+		return;
+	}
+
+	//UserActivity::add($tblProblemsId);
+
+	$userAcl = User::getAcl();
+	$userAcl->fetchGroups();
+
+	if (!$userAcl->hasTableAcl($zasobObj->ID)) {
+		echo '<div class="alert alert-error">' . "Brak uprawnień do tabeli ID={$zasobObj->ID}" . '</div>';
+		//echo UserActivity::showSimpleList();
+		return;
+	}
+
+	if (!$userAcl->hasTableAcl($korespObj->ID)) {
+		echo '<div class="alert alert-error">' . "Brak uprawnień do tabeli Korespondencja (ID={$korespObj->ID})" . '</div>';
+		//echo UserActivity::showSimpleList();
+		return;
+	}
+
+	$tblAcl = $userAcl->getTableAcl($zasobObj->ID);
+	$korespAcl = $userAcl->getTableAcl($korespObj->ID);
+
+	$forceTblAclInit = ('1' == V::get('_force', '', $_GET));
+	$tblAcl->init($forceTblAclInit);
+	$korespAcl->init($forceTblAclInit);
+
+	$module = new Ahmes_Reklamacje($tblAcl, $korespAcl, $_GET);
+	$module->run();
+}
+
+
+class Ahmes_Reklamacje {
+
+	private $_args = null;
+	private $_tbl = null;
+	private $_acl = null;
+	private $_zasobID = null;
+	private $_dataSource = null;
+	private $_htmlID = '';
+
+	public function __construct($tblAcl, $korespAcl, $args) {
+		$this->_args = $args;
+		$this->_tbl = $tblAcl->getName();
+		$this->_acl = $tblAcl;
+		$this->_korespAcl = $korespAcl;
+		$this->_zasobID = $tblAcl->getID();
+		Lib::loadClass('Data_Source');
+		$this->_dataSource = new Data_Source($tblAcl->getDB());
+		$this->_dataSource->setTable($tblAcl->getName());
+		$realFieldList = $tblAcl->getRealFieldList();
+		$this->_dataSource->setCols($realFieldList);
+		$this->_dataSource->setColTypes($tblAcl->getTypes());
+		$this->_dataSource->setVirtualCols($tblAcl->getVirtualFieldList());
+		$this->_dataSource->setFieldGroupWrite('A_ADM_COMPANY', $tblAcl->hasFieldType('A_ADM_COMPANY'));
+		$this->_dataSource->setFieldGroupRead('A_CLASSIFIED', $tblAcl->hasFieldType('A_CLASSIFIED'));
+		$this->_dataSource->setAccessFltrAllowed(!$tblAcl->hasSuperAccessPerms());
+		$this->_htmlID = 'Ahmes_Reklamacje';
+
+		$adminFields = array('A_RECORD_CREATE_DATE', 'A_RECORD_CREATE_AUTHOR', 'A_RECORD_UPDATE_DATE', 'A_RECORD_UPDATE_AUTHOR');
+		foreach ($adminFields as $vAdmFld) {
+			if (!in_array($vAdmFld, $realFieldList) && $tblAcl->hasFieldType($vAdmFld)) {
+				$this->_dataSource->addCol($vAdmFld);
+			}
+		}
+	}
+
+	public function run() {
+		Lib::loadClass('SE_Layout');
+		SE_Layout::menu();
+		$task = V::get('task', '', $this->_args);
+		switch ($task) {
+			case 'create_problem':
+				$id_koresp = V::get('id_koresp', '', $this->_args);
+				if (!$id_koresp) {
+					echo '<div class="alert alert-error">' . "Brak numeru z dziennika pism!" . '</div>';
+				} else {
+					$this->taskCreateProblem($id_koresp);
+				}
+				break;
+			case 'create_koresp_out':
+				$id_problem = V::get('id_problem', '', $this->_args);
+				if (!$id_problem) {
+					echo '<div class="alert alert-error">' . "Brak numeru z dziennika pism!" . '</div>';
+				} else {
+					$this->taskCreateKorespOut($id_problem);
+				}
+				break;
+			default:
+				echo '<div class="alert alert-error">' . "Brak zadania do wykonania!" . '</div>';
+		}
+	}
+
+	private function renderError($msg) {
+		echo '<div class="alert alert-error">' . $msg . '</div>';
+	}
+
+	private function getKoresp($id_koresp) {
+		$db = DB::getDB();
+		if (!$db) return false;
+		$koresp = $db->get_by_id('IN7_DZIENNIK_KORESP', $id_koresp);
+		return $koresp;
+	}
+
+	private function getProblem($id_problem) {
+		$db = DB::getDB();
+		if (!$db) return false;
+		$problem = $db->get_by_id('PROBLEMS', $id_problem);
+		return $problem;
+	}
+
+	private function checkKorespUsed($id_koresp) {
+		$db = DB::getDB();
+		if (!$db) return false;
+
+		$sql = "select count(1) as cnt
+			from `{$this->_tbl}` as p
+			where p.`ID_KORESP_IN`='{$id_koresp}'
+		";
+		$res = $db->query($sql);
+		if ($r = $db->fetch($res)) {
+			if ($r->cnt > 0) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private function checkProblem($problem) {
+		return true;
+	}
+
+	private function taskCreateProblem($id_koresp) {
+		$koresp = $this->getKoresp($id_koresp);
+		if (!$koresp) {
+			$this->renderError("Brak dostępu do korespondecji lub korespondencja nie istnieje");
+			return;
+		}
+
+		if ($this->checkKorespUsed($id_koresp)) {
+			$this->renderError("Korespondecja została już przypisana do problemu");
+			return;
+		}
+
+		if ('1' == V::get('frm_sent', '', $_POST)) {
+			$frmSaved = $this->saveCreateProblemForm($koresp, $_POST);
+			if ($frmSaved) return;
+		}
+		$this->renderCreateProblemForm($koresp);
+	}
+
+	public function saveCreateProblemForm($koresp, $args) {
+		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
+
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">TODO: save('.$koresp->ID.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($args);echo'</pre>';}
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">acl (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_acl);echo'</pre>';}
+		$dbID = $this->_acl->getDB();
+		$db = DB::getDB($dbID);
+
+		if (!$db) return false;
+
+		$tblName = $this->_acl->getName();
+
+		$sqlObj = new stdClass();
+		$fields = $this->_acl->getFields();
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">fields (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($fields);echo'</pre>';}
+		foreach ($fields as $kID => $vField) {
+			if (!$this->_acl->isAllowed($kID, 'C')) {
+				continue;
+			}
+			if (array_key_exists("f{$kID}", $args)) {
+				$sqlObj->{$vField['name']} = $args["f{$kID}"];
+
+				if (empty($args["f{$kID}"]) && strlen($args["f{$kID}"]) == 0) {// fix bug in input type date and value="0000-00-00"
+					$sqlObj->{$vField['name']} = $this->_acl->fixEmptyValueFromUser($kID);
+				}
+			}
+		}
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sqlObj);echo'</pre>';}
+
+		$sqlObj->ID_KORESP_IN = $koresp->ID;
+		$retID = $db->ADD_NEW_OBJ($tblName, $sqlObj);
+
+		if ($retID > 0) {
+			?>
+			<div class="alert alert-success">
+				Utworzono pomyślnie rekord Nr <?php echo $retID; ?>
+			</div>
+			<?php
+			return true;
+		}
+
+		?>
+		<div class="alert alert-error">
+			Wystąpił błąd podczas tworzenia rekordu
+			<?php
+			if ($db->has_errors()) {
+				$outArr = array();
+				$errorsSql = $db->get_errors();
+				foreach ($errorsSql as $vErr) {
+					if (substr($vErr, 0, 18) == 'SQL QUERY FAILED: ') {
+						$vErr = substr($vErr, 18);
+						// Duplicate entry '123456-1' for key 'P_NIP'
+						if (substr($vErr, 0, 16) == 'Duplicate entry ') {
+						}
+					}
+					$outArr[] = $vErr;
+				}
+				echo implode('<br>', $outArr);
+			}
+			?>
+		</div>
+		<?php
+		return false;
+	}
+
+	/*
+	 * @from TableAjax::sendAjaxCreate($args)
+	 */
+	public function renderCreateProblemForm($koresp) {
+		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
+
+		$cols = array();
+		$forceFilterInit = array();
+		foreach ($this->_args as $k => $v) {
+			if (strlen($k) > 4 && substr($k, 0, 3) == 'ff_' && !empty($v)) {// force filter prefix
+				$fldName = substr($k, 3);
+				$forceFilterInit[$fldName] = $v;
+			}
+		}
+		$forceFilterInit['data_nad_pism'] = $koresp->K_DATA_OTRZYMANEJ_KORESP;
+		$forceFilterInit['data_wpl_pism'] = $koresp->K_DATA_OTRZYM_KORESP;
+		$forceFilterInit['Osoba'] = $koresp->K_OD_KOGO;
+		$forceFilterInit['ID_PROJECT'] = $koresp->ID_PROJECT;
+
+		$fieldsList = $this->_acl->getFields();
+		foreach ($fieldsList as $kID => $vCol) {
+			$defaultValue = '';
+			if ($vCol['name'] == 'ID') {
+				unset($fieldsList[$kID]);
+				continue;
+			}
+
+			if (!empty($forceFilterInit[$vCol['name']])) {
+				$defaultValue = $forceFilterInit[$vCol['name']];
+			}
+
+			// TODO: read from session cache
+			$cols[$kID] = V::get("f{$kID}", $defaultValue, $_POST);
+
+			$fieldsList[$kID]['label'] = (!empty($vCol['label']))? $vCol['label'] : $vCol['name'];
+		}
+
+		$korespFldsList = $this->_korespAcl->getFields();
+		$korespFldsList = array_filter($korespFldsList, function($fld) {
+			$korespFldsName = array();
+			$korespFldsName[] = 'ID';
+			$korespFldsName[] = 'K_OD_KOGO';
+			$korespFldsName[] = 'K_TYP_KORESP';
+			$korespFldsName[] = 'K_TYP_RODZAJ';
+			$korespFldsName[] = 'K_DATA_OTRZYMANEJ_KORESP';
+			$korespFldsName[] = 'K_DATA_OTRZYM_KORESP';
+			if (in_array($fld['name'], $korespFldsName)) {
+				return true;
+			}
+			return false;
+		});
+
+		Lib::loadClass('SE_Layout');
+		?>
+		<div class="container AjaxFrmHorizontalEdit">
+		<form class="form-horizontal" action="" method="post">
+			<input type="hidden" name="frm_sent" value="1">
+			<fieldset>
+				<legend>Dodaj nowy Problem/Reklamację na podstawie pisma nr <?php echo $koresp->ID; ?></legend>
+
+				<blockquote>
+					<?php foreach ($korespFldsList as $fldId => $vFld) : ?>
+						<p><small><b><?php echo $vFld['label']; ?>: </b> <?php echo $koresp->{$vFld['name']}; ?></small></p>
+					<?php endforeach; ?>
+				</blockquote>
+				<?php $tabindex = 0; foreach ($fieldsList as $kID => $vCol) : ?>
+					<?php if ($this->_acl->isAllowed($kID, 'C')) : ?>
+						<div class="control-group">
+							<label class="control-label" for="<?php echo "f{$kID}"; ?>"><?php echo $vCol['label']; ?>
+								<i class="icon-info-sign frm-help" data-toggle="popover" data-trigger="hover" title="" data-content="<?php echo htmlspecialchars($vCol['opis']); ?>" data-original-title="<?php echo "[{$kID}] {$vCol['name']}"; ?>"></i>
+								<?php $perms = $this->_acl->getFieldPerms($kID); SE_Layout::hotKeyDBG($perms); ?>
+							</label>
+							<div class="controls">
+								<?php
+									$fieldParams = array('appendBack'=>true, 'tabindex'=>(++$tabindex), 'maxGrid'=>8);
+									echo $this->_acl->showFormItem('C', $kID, "f{$kID}", $cols[$kID], $fieldParams);
+								?>
+							</div>
+						</div>
+					<?php endif; ?>
+				<?php endforeach; ?>
+
+				<div class="control-group">
+					<div class="controls">
+						<button type="submit" class="btn btn-primary" tabindex="<?php echo (++$tabindex); ?>">Dodaj rekord</button>
+					</div>
+				</div>
+
+			</fieldset>
+		</form>
+		</div>
+
+<script>
+jQuery(document).ready(function(){
+	jQuery('textarea').autosize();
+
+	jQuery('.frm-help').popover({trigger:'hover'});
+});
+</script>
+		<?php
+	}
+
+	private function taskCreateKorespOut($id_problem) {
+		$problem = $this->getProblem($id_problem);
+		if (!$problem) {
+			$this->renderError("Brak dostępu do problemu lub problem nie istnieje");
+			return;
+		}
+
+		if (!$this->checkProblem($problem)) {
+			$this->renderError("Problem nie może zostać użyty");
+			return;
+		}
+
+		if ('1' == V::get('frm_sent', '', $_POST)) {
+			$frmSaved = $this->saveCreateKorespOutForm($problem, $_POST);
+			if ($frmSaved) return;
+		}
+		$this->renderCreateKorespOutForm($problem);
+	}
+
+	public function renderCreateKorespOutForm($problem) {
+		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
+
+		$forceFilterInit = array();
+		foreach ($this->_args as $k => $v) {
+			if (strlen($k) > 4 && substr($k, 0, 3) == 'ff_' && !empty($v)) {// force filter prefix
+				$fldName = substr($k, 3);
+				$forceFilterInit[$fldName] = $v;
+			}
+		}
+		$forceFilterInit['K_TYP_KORESP'] = 'OUT';
+		$forceFilterInit['K_DATA_OTRZYMANEJ_KORESP'] = date('Y-m-d');
+		$forceFilterInit['K_OD_KOGO'] = $problem->Osoba;
+
+		$fieldsList = $this->_korespAcl->getFields();
+		$fieldsList = array_filter($fieldsList, function($vCol) {
+			return ($vCol['name'] != 'ID');
+		});
+		$fieldsList = array_map(function($vCol) {
+			$vCol['label'] = (!empty($vCol['label']))? $vCol['label'] : $vCol['name'];
+			return $vCol;
+		}, $fieldsList);
+
+		$cols = array();
+		foreach ($fieldsList as $kID => $vCol) {
+			$defaultValue = '';
+			if (!empty($forceFilterInit[$vCol['name']])) {
+				$defaultValue = $forceFilterInit[$vCol['name']];
+			}
+
+			// TODO: read from session cache
+			$cols[$kID] = V::get("f{$kID}", $defaultValue, $_POST);
+		}
+
+		$problFldsList = $this->_acl->getFields();
+		$problFldsList = array_filter($problFldsList, function($fld) {
+			$problFldsName = array();
+			$problFldsName[] = 'ID';
+			$problFldsName[] = 'Osoba';
+			$problFldsName[] = 'nazwa_jedn';
+			$problFldsName[] = 'miejscowosc';
+			$problFldsName[] = 'data_nad_pism';
+			$problFldsName[] = 'data_wpl_pism';
+			$problFldsName[] = 'data_real';
+			$problFldsName[] = 'A_PROBLEM_DESC_HTML';
+			if (in_array($fld['name'], $problFldsName)) {
+				return true;
+			}
+			return false;
+		});
+
+		Lib::loadClass('SE_Layout');
+		?>
+		<div class="container AjaxFrmHorizontalEdit">
+		<form class="form-horizontal" action="" method="post">
+			<input type="hidden" name="frm_sent" value="1">
+			<fieldset>
+				<legend>Dodaj korespondencję na podstawie problemu nr <?php echo $problem->ID; ?></legend>
+
+				<blockquote>
+					<?php foreach ($problFldsList as $fldId => $vFld) : ?>
+						<p><small><b><?php echo $vFld['label']; ?>: </b> <?php echo $problem->{$vFld['name']}; ?></small></p>
+					<?php endforeach; ?>
+				</blockquote>
+				<?php $tabindex = 0; foreach ($fieldsList as $kID => $vCol) : ?>
+					<?php if ($this->_korespAcl->isAllowed($kID, 'C')) : ?>
+						<div class="control-group">
+							<label class="control-label" for="<?php echo "f{$kID}"; ?>"><?php echo $vCol['label']; ?>
+								<i class="icon-info-sign frm-help" data-toggle="popover" data-trigger="hover" title="" data-content="<?php echo htmlspecialchars($vCol['opis']); ?>" data-original-title="<?php echo "[{$kID}] {$vCol['name']}"; ?>"></i>
+								<?php $perms = $this->_korespAcl->getFieldPerms($kID); SE_Layout::hotKeyDBG($perms); ?>
+							</label>
+							<div class="controls">
+								<?php
+									$fieldParams = array('appendBack'=>true, 'tabindex'=>(++$tabindex), 'maxGrid'=>8);
+									echo $this->_korespAcl->showFormItem('C', $kID, "f{$kID}", $cols[$kID], $fieldParams);
+								?>
+							</div>
+						</div>
+					<?php endif; ?>
+				<?php endforeach; ?>
+
+				<div class="control-group">
+					<div class="controls">
+						<button type="submit" class="btn btn-primary" tabindex="<?php echo (++$tabindex); ?>">Dodaj rekord</button>
+					</div>
+				</div>
+
+			</fieldset>
+		</form>
+		</div>
+
+<script>
+jQuery(document).ready(function(){
+	jQuery('textarea').autosize();
+
+	jQuery('.frm-help').popover({trigger:'hover'});
+});
+</script>
+		<?php
+	}
+
+	public function saveCreateKorespOutForm($problem, $args) {
+		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
+
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">TODO: save('.$problem->ID.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($args);echo'</pre>';}
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">acl (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_korespAcl);echo'</pre>';}
+		$dbID = $this->_korespAcl->getDB();
+		$db = DB::getDB($dbID);
+
+		if (!$db) return false;
+
+		$tblName = $this->_korespAcl->getName();
+
+		$sqlObj = new stdClass();
+		$fields = $this->_korespAcl->getFields();
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">fields (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($fields);echo'</pre>';}
+		foreach ($fields as $kID => $vField) {
+			if (!$this->_korespAcl->isAllowed($kID, 'C')) {
+				continue;
+			}
+			if (array_key_exists("f{$kID}", $args)) {
+				$sqlObj->{$vField['name']} = $args["f{$kID}"];
+
+				if (empty($args["f{$kID}"]) && strlen($args["f{$kID}"]) == 0) {// fix bug in input type date and value="0000-00-00"
+					$sqlObj->{$vField['name']} = $this->_korespAcl->fixEmptyValueFromUser($kID);
+				}
+			}
+		}
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sqlObj);echo'</pre>';}
+
+		$retID = $db->ADD_NEW_OBJ($tblName, $sqlObj);
+
+		if ($retID > 0) {
+			?>
+			<div class="alert alert-success">
+				Utworzono pomyślnie rekord Nr <?php echo $retID; ?>
+			</div>
+			<?php
+
+			$dbProblemId = $this->_acl->getDB();
+			$dbProblem = DB::getDB($dbProblemId);
+			$tblProblemName = $this->_acl->getName();
+			$sqlProblemObj = new stdClass();
+			$sqlProblemObj->ID = $problem->ID;
+			$sqlProblemObj->ID_KORESP_OUT = $retID;
+			// TODO: ? $sqlProblemObj->data real "data realizacji" defautl today - date('Y-m-d')
+			$affectes = $dbProblem->UPDATE_OBJ($tblProblemName, $sqlProblemObj);
+
+			return true;
+		}
+
+		?>
+		<div class="alert alert-error">
+			Wystąpił błąd podczas tworzenia rekordu
+			<?php
+			if ($db->has_errors()) {
+				$outArr = array();
+				$errorsSql = $db->get_errors();
+				foreach ($errorsSql as $vErr) {
+					if (substr($vErr, 0, 18) == 'SQL QUERY FAILED: ') {
+						$vErr = substr($vErr, 18);
+						// Duplicate entry '123456-1' for key 'P_NIP'
+						if (substr($vErr, 0, 16) == 'Duplicate entry ') {
+						}
+					}
+					$outArr[] = $vErr;
+				}
+				echo implode('<br>', $outArr);
+			}
+			?>
+		</div>
+		<?php
+		return false;
+	}
+
+	public function ___sendAjaxCreateSave($args) {
+		header("Content-type: application/json");
+		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
+		sleep(1);// TODO: RMME DBG loading
+
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">TODO: save ID(' . $id . ') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($args);echo'</pre>';}
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">acl (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_acl);echo'</pre>';}
+		$dbID = $this->_acl->getDB();
+		$db = DB::getDB($dbID);
+
+		if (!$db) {
+			header('HTTP/1.0 406 Not Acceptable');
+			echo '{"type":"ERROR", "msg": "' . "Błąd połączenia z bazą danych!" . '"}';
+			exit;
+		}
+
+		$tblName = $this->_acl->getName();
+
+		$sqlObj = new stdClass();
+		$fields = $this->_acl->getFields();
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">fields (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($fields);echo'</pre>';}
+		foreach ($fields as $kID => $vField) {
+			if (!$this->_acl->isAllowed($kID, 'C')) {
+				continue;
+			}
+			if (array_key_exists("f{$kID}", $args)) {
+				$sqlObj->{$vField['name']} = $args["f{$kID}"];
+
+				if (empty($args["f{$kID}"]) && strlen($args["f{$kID}"]) == 0) {// fix bug in input type date and value="0000-00-00"
+					$sqlObj->{$vField['name']} = $this->_acl->fixEmptyValueFromUser($kID);
+				}
+			}
+		}
+		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sqlObj);echo'</pre>';}
+
+		$retID = $db->ADD_NEW_OBJ($tblName, $sqlObj);
+
+		$retJson = new stdClass();
+		$retJson->type = '';
+		$retJson->msg = '';
+
+		if ($retID > 0) {
+			$retJson->type = 'SUCCESS';
+			$retJson->msg = "Utworzono pomyślnie rekord: ID = {$retID}";
+			$retJson->id = $retID;
+		} else {
+			header('HTTP/1.0 404 Not Found');
+			$retJson->type = 'ERROR';
+			$retJson->msg = "";
+			if ($db->has_errors()) {
+				$outArr = array();
+				$errorsSql = $db->get_errors();
+				foreach ($errorsSql as $vErr) {
+					if (substr($vErr, 0, 18) == 'SQL QUERY FAILED: ') {
+						$vErr = substr($vErr, 18);
+						// Duplicate entry '123456-1' for key 'P_NIP'
+						if (substr($vErr, 0, 16) == 'Duplicate entry ') {
+						}
+					}
+					$outArr[] = $vErr;
+				}
+				$retJson->msg .= implode('<br>', $outArr);
+			}
+		}
+
+		echo json_encode($retJson);
+		exit;
+	}
+
+}