Ver Fonte

Merge branch 'master' of biuro.biall-net.pl:plabudda/se

# By Piotr Labudda
# Via Piotr Labudda
* 'master' of biuro.biall-net.pl:plabudda/se:
  updates in ZamZlec for pro-netmedia
  added project Typspecial in ZamZlec for pro-netmedia, hide ZmaZlec list if no id project
  update the_geom from hist in HIST view
a.binder há 9 anos atrás
pai
commit
5fbb6a47e3

+ 8 - 2
SE/se-lib/Data_Source.php

@@ -182,7 +182,7 @@ class Data_Source {
 			}
 			$sqlCols = implode(", ", $sqlColsList);
 		}
-		DBG::_('DBG_DS', '>0', "sqlCols", $sqlCols, __CLASS__, __FUNCTION__, __LINE__);
+		DBG::_('DBG_DS', '>2', "sqlCols", $sqlCols, __CLASS__, __FUNCTION__, __LINE__);
 		return $sqlCols;
 	}
 
@@ -728,10 +728,15 @@ class Data_Source {
 
 	public function getHistItems($id, $params = array()) {
 		$ret = array();
+		DBG::_('DBG_DS', '>1', "params", $params, __CLASS__, __FUNCTION__, __LINE__);
 		$sql_tbl = $this->_tbl . "_HIST";
 		$sql_cols = $this->_getSqlCols();
 		$sql_where = "t.`ID_USERS2`='{$id}'";
 
+		$idHist = V::get('ID', 0, $params, 'int');
+		if ($idHist > 0) {
+			$sql_where .= "\n and t.`ID`='{$idHist}'";
+		}
 		$paramNotEmptyFlds = V::get('notEmptyFlds', '', $params);
 		if (!empty($paramNotEmptyFlds) && is_array($paramNotEmptyFlds)) {
 			$sqlWhereOr = array();
@@ -748,7 +753,7 @@ class Data_Source {
 			where {$sql_where}
 			order by ID DESC
 		";
-if(V::get('DBG_DS', 0, $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>'."\n\n";}
+		DBG::_('DBG_DS', '>1', "sql", $sql, __CLASS__, __FUNCTION__, __LINE__);
 		$res = $this->_db->query($sql);
 		while ($r = $this->_db->fetch($res)) {
 			$r->_author = $r->A_RECORD_UPDATE_AUTHOR;
@@ -763,6 +768,7 @@ if(V::get('DBG_DS', 0, $_GET) > 2){echo'<pre style="max-height:200px;overflow:au
 
 			$ret[$r->ID] = $r;
 		}
+		DBG::_('DBG_DS', '>2', "ret", $ret, __CLASS__, __FUNCTION__, __LINE__);
 		return $ret;
 	}
 

+ 8 - 32
SE/se-lib/Route/UrlAction/ProjektyProNetMediaBudget.php

@@ -268,43 +268,19 @@ dostęp dla zarządu i os. odp.	kwota końcowa
 		return $data;
 	}
 
-	public function getWidgetProject() {
+	public function getWidgetProject() {// mv to Route_UrlAction_ProjektyProNetMediaZamZlec, use Router::getRoute('UrlAction_ProjektyProNetMediaZamZlec')->getWidgetProject()
 		$widgetProject = array();
 		$widgetProject['idTabela'] = 1656;// TODO: idZasob for TABELA Projekty
 		$widgetProject['idKomorka'] = 1658;// TODO: idZasob for KOMORKA Projekty.P_ID
 		$widgetProject['fieldName'] = 'ID_PROJECT';
 		$widgetProject['dataUrl'] = "index.php?_route=UrlAction_ProjektyProNetMediaZamZlec&_task=typespecial&fld={$widgetProject['fieldName']}";
-		$widgetProject['typeSpecial'] = Typespecial::getInstance($widgetProject['idKomorka'], $colName = $widgetProject['fieldName']);
-		return $widgetProject;
-	}
-
-	public function typespecialAction() {
-		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
-		$fld = V::get('fld', '', $_GET);
-		$widgetProject = $this->getWidgetProject();
-
-		header("Content-type: application/json");
-		switch ($fld) {
-			case 'ID_PROJECT': {
-					$typeSpecialIdProject = Typespecial::getInstance($widgetProject['idKomorka'], $colName = $widgetProject['fieldName']);
-
-					$query = V::get('q', '', $_REQUEST);
-					$rawRows = null;
-					$rows = $typeSpecialIdProject->getValuesWithExports($query);
-					if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">rows('.$query.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($rows);echo'</pre>';}
-					foreach ($rows as $kID => $vItem) {
-						$itemJson = new stdClass();
-						$itemJson->id = $vItem->id;
-						$itemJson->name = $vItem->param_out;
-						if (!empty($vItem->exports)) {
-							$itemJson->exports = $vItem->exports;
-						}
-						$jsonData[] = $itemJson;
-					}
-					echo json_encode($jsonData);
-				}
-				break;
+		$widgetProject['typeSpecial'] = null;
+		$acl = User::getAcl()->getObjectAcl('default_db', 'IN7_MK_BAZA_DYSTRYBUCJI');
+		if ($acl) {
+			$acl->init($force = false);
+			$widgetProject['typeSpecial'] = Typespecial::getInstance($widgetProject['idKomorka'], $colName = $widgetProject['fieldName']);
 		}
+		return $widgetProject;
 	}
 
 	public function budgetView($data, $viewParams) {
@@ -352,7 +328,7 @@ dostęp dla zarządu i os. odp.	kwota końcowa
 						<?php else : ?>
 							<input type="number" name="<?= $widgetProject['fieldName']; ?>" value="<?= $data['id_project']; ?>" class="form-control">
 						<?php endif; ?>
-						</div>
+					</div>
 					<input type="submit" value="Wybierz" class="btn btn-primary">
 				</form>
 			<?php endif; ?>

+ 103 - 39
SE/se-lib/Route/UrlAction/ProjektyProNetMediaZamZlec.php

@@ -1,6 +1,7 @@
 <?php
 
 Lib::loadClass('RouteBase');
+Lib::loadClass('Typespecial');
 Lib::loadClass('TypespecialVariable');
 Lib::loadClass('Request');
 Lib::loadClass('Response');
@@ -28,24 +29,44 @@ class Route_UrlAction_ProjektyProNetMediaZamZlec extends RouteBase {// TODO: Url
 		$fld = V::get('fld', '', $_GET);
 		switch ($fld) {
 			case 'id_company': {
-					$typeSpecialCompanies = TypespecialVariable::getInstance(-1, '__COMPANIES');
-
-					$query = V::get('q', '', $_REQUEST);
-					$rawRows = null;
-					$rows = $typeSpecialCompanies->getValuesWithExports($query);
-					if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">rows('.$query.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($rows);echo'</pre>';}
-					foreach ($rows as $kID => $vItem) {
-						$itemJson = new stdClass();
-						$itemJson->id = $vItem->id;
-						$itemJson->name = $vItem->param_out;
-						if (!empty($vItem->exports)) {
-							$itemJson->exports = $vItem->exports;
-						}
-						$jsonData[] = $itemJson;
+				$typeSpecialCompanies = TypespecialVariable::getInstance(-1, '__COMPANIES');
+
+				$query = V::get('q', '', $_REQUEST);
+				$rawRows = null;
+				$rows = $typeSpecialCompanies->getValuesWithExports($query);
+				if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">rows('.$query.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($rows);echo'</pre>';}
+				foreach ($rows as $kID => $vItem) {
+					$itemJson = new stdClass();
+					$itemJson->id = $vItem->id;
+					$itemJson->name = $vItem->param_out;
+					if (!empty($vItem->exports)) {
+						$itemJson->exports = $vItem->exports;
+					}
+					$jsonData[] = $itemJson;
+				}
+				echo json_encode($jsonData);
+			}
+			break;
+			case 'ID_PROJECT': {
+				$widgetProject = $this->getWidgetProject();
+				$typeSpecialIdProject = Typespecial::getInstance($widgetProject['idKomorka'], $colName = $widgetProject['fieldName']);
+
+				$query = V::get('q', '', $_REQUEST);
+				$rawRows = null;
+				$rows = $typeSpecialIdProject->getValuesWithExports($query);
+				if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">rows('.$query.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($rows);echo'</pre>';}
+				foreach ($rows as $kID => $vItem) {
+					$itemJson = new stdClass();
+					$itemJson->id = $vItem->id;
+					$itemJson->name = $vItem->param_out;
+					if (!empty($vItem->exports)) {
+						$itemJson->exports = $vItem->exports;
 					}
-					echo json_encode($jsonData);
+					$jsonData[] = $itemJson;
 				}
-				break;
+				echo json_encode($jsonData);
+			}
+			break;
 		}
 	}
 
@@ -61,6 +82,8 @@ class Route_UrlAction_ProjektyProNetMediaZamZlec extends RouteBase {// TODO: Url
 			$data['widgetCompanies']['fieldName'] = 'id_company';
 			$data['widgetCompanies']['dataUrl'] = "index.php?_route=UrlAction_ProjektyProNetMediaZamZlec&_task=typespecial&fld={$data['widgetCompanies']['fieldName']}";
 			$data['widgetCompanies']['typeSpecial'] = TypespecialVariable::getInstance(-1, '__COMPANIES');
+			$data['widgetProject'] = $this->getWidgetProject();
+
 			$this->zamZlecFormView($data);
 		} catch (Exception $e) {
 			UI::alert('danger', "Error #" . $e->getCode() .  "|" . $e->getLine() .  ": " . $e->getMessage());
@@ -68,6 +91,21 @@ class Route_UrlAction_ProjektyProNetMediaZamZlec extends RouteBase {// TODO: Url
 		if (1 != V::get('_print', '', $_GET)) UI::dol();
 	}
 
+	public function getWidgetProject() {
+		$widgetProject = array();
+		$widgetProject['idTabela'] = 1656;// TODO: idZasob for TABELA Projekty
+		$widgetProject['idKomorka'] = 1658;// TODO: idZasob for KOMORKA Projekty.P_ID
+		$widgetProject['fieldName'] = 'ID_PROJECT';
+		$widgetProject['dataUrl'] = "index.php?_route=UrlAction_ProjektyProNetMediaZamZlec&_task=typespecial&fld={$widgetProject['fieldName']}";
+		$widgetProject['typeSpecial'] = null;
+		$acl = User::getAcl()->getObjectAcl('default_db', 'IN7_MK_BAZA_DYSTRYBUCJI');
+		if ($acl) {
+			$acl->init($force = false);
+			$widgetProject['typeSpecial'] = Typespecial::getInstance($widgetProject['idKomorka'], $colName = $widgetProject['fieldName']);
+		}
+		return $widgetProject;
+	}
+
 	public function addZlecenieAction() {
 		$id_company = V::get('id_company', 0, $_REQUEST, 'int');
 		$id_project = V::get('ID_PROJECT', 0, $_REQUEST, 'int');
@@ -436,20 +474,21 @@ class Route_UrlAction_ProjektyProNetMediaZamZlec extends RouteBase {// TODO: Url
 		$id_company = V::get('id_company', 0, $data);
 		$items_count = V::get('items_count', 0, $data);
 		$widgetCompanies = V::get('widgetCompanies', array(), $data);
+		$widgetProject = V::get('widgetProject', array(), $data);
 		$saveOrderNotesLink = "index.php?_route=UrlAction_ProjektyProNetMediaZamZlec&_task=updateOrderNoteAjax";
 
-		$sqlWhere = '';
-		if ($id_project > 0) $sqlWhere = "where o.ID_PROJECT = {$id_project}";
-		$projOrders = DB::getPDO()->fetchAll("
-			select o.*
-					, p.M_DIST_DEALNUM as obcy_nr_sprawy
-			from CRM_LISTA_ZASOBOW_ORDERS o
-				left join IN7_MK_BAZA_DYSTRYBUCJI p on(p.ID = o.ID_PROJECT)
-				left join COMPANIES c on(c.ID = o.ID_COMPANIES)
-			{$sqlWhere}
-			order by ID DESC
-			limit 100
-		");
+		$projOrders = ($id_project > 0)
+			? DB::getPDO()->fetchAll("
+					select o.*
+							, p.M_DIST_DEALNUM as obcy_nr_sprawy
+					from CRM_LISTA_ZASOBOW_ORDERS o
+						left join IN7_MK_BAZA_DYSTRYBUCJI p on(p.ID = o.ID_PROJECT)
+						left join COMPANIES c on(c.ID = o.ID_COMPANIES)
+					where o.ID_PROJECT = {$id_project}
+					order by ID DESC
+					limit 100
+				")
+			: array();
 
 ?>
 <div class="container" style="margin-top:2em">
@@ -458,7 +497,24 @@ class Route_UrlAction_ProjektyProNetMediaZamZlec extends RouteBase {// TODO: Url
 		<div class="form-group">
 			<label for="id_project" class="col-sm-2 control-label">Projekt</label>
 			<div class="col-sm-4">
-				<input type="number" name="ID_PROJECT" value="<?php echo $id_project; ?>" class="form-control">
+				<?php if ($widgetProject['typeSpecial']) : ?>
+					<?php
+						$fName = $widgetProject['fieldName'];
+						$fldParams = array();
+						$fldParams['allowCreate'] = false;
+						$fldParams['ajaxDataUrlBase'] = $widgetProject['dataUrl'];
+						if ($data['id_project'] > 0) {
+							$tsValues = $widgetProject['typeSpecial']->getValuesWithExports($q = $data['id_project']);
+							if (!empty($tsValues[ $data['id_project'] ])) {
+								$fldParams['typespecialValue'] = $tsValues[ $data['id_project'] ]->param_out;
+							}
+						}
+						//$fldParams['ajaxDataUrlBase'] .= "&DBG_TS=3";
+						echo $widgetProject['typeSpecial']->showFormItem($idTbl = $widgetProject['idTabela'], $fName, $selValue = $data['id_project'], $fldParams);
+					?>
+				<?php else : ?>
+					<input type="number" name="<?= $widgetProject['fieldName']; ?>" value="<?= $data['id_project']; ?>" class="form-control">
+				<?php endif; ?>
 			</div>
 		</div>
 		<div class="form-group">
@@ -508,6 +564,7 @@ class Route_UrlAction_ProjektyProNetMediaZamZlec extends RouteBase {// TODO: Url
 .orders_cell__order_notes .edit_note_btn { display:none }
 .orders_cell__order_notes:hover .edit_note_btn { display:inline-block }
 </style>
+<?php if (!empty($projOrders)) : ?>
 	<table class="table table-bordered table-hover">
 		<thead>
 			<tr>
@@ -572,6 +629,7 @@ class Route_UrlAction_ProjektyProNetMediaZamZlec extends RouteBase {// TODO: Url
 		</tbody>
 	</table>
 </div>
+<?php endif; ?>
 <link rel="stylesheet" type="text/css" href="static/sweetalert2.min.css">
 <script src="static/sweetalert2.min.js"></script>
 <script>
@@ -779,7 +837,7 @@ body { font-size:12px; line-height:1.3em }
 			<td></td>
 		</tr>
 		<tr>
-			<td colspan="5"><b>UWAGI: NA FAKTURZE VAT NALEŻY UMIESZCZAĆ CZYTELNY NR ZLECENIA</b></td>
+			<td colspan="5"><b>UWAGI: NA FAKTURZE VAT NALEŻY UMIEŚCIĆ CZYTELNY NR ZLECENIA</b></td>
 			<td></td>
 		</tr>
 	</table>
@@ -1165,7 +1223,7 @@ body { font-size:12px; line-height:1.3em }
 		$labels['main'] = ($isTypeZlecenie) ? "Zlecenie" : "Zamówienie";
 		$labels['comA'] = ($isTypeZlecenie) ? "Zleceniodawca" : "Zamawiający";
 		$labels['comB'] = ($isTypeZlecenie) ? "Zleceniobiorca" : "Dostawca";
-		$labels['invoiceMessage'] = "NA FAKTURZE VAT NALEŻY UMIESZCZAĆ CZYTELNY NR " . (($isTypeZlecenie) ? "ZLECENIA" : "ZAMÓWIENIA");
+		$labels['invoiceMessage'] = "NA FAKTURZE VAT NALEŻY UMIEŚCIĆ CZYTELNY NR " . (($isTypeZlecenie) ? "ZLECENIA" : "ZAMÓWIENIA");
 		$labels['offer'] = "Zamawiający zleca Dostawcy dostawę poniższych materiałów na wskazanych poniżej warunkach. Zgodnie z ofertą ";
 		if ($isTypeZlecenie) $labels['offer'] = "Zleceniodawca niniejszym składa zlecenie na wskazanych poniżej warunkach zgodnie z ofertą Zleceniobiorcy z dnia ";
 		$labels['firstPosFieldLabel'] = ($isTypeZlecenie)? 'Przedmiot zlecenia' : 'Wyszczególnienie';
@@ -1199,7 +1257,9 @@ body { font-size:12px; line-height:1.3em }
 				['text', 'Wynagrodzenie objęte niniejszym zleceniem jest wynagrodzeniem ryczałtowym.']
 			];
 			$conditions[] = [
-				['text', 'Termin płatności: 30 dni od daty wpływu do siedziby Zleceniodawcy wszystkich prawidłowych i kompletnych dokumentów, o których mowa w pkt 6 i 7 poniżej w trybie zgodnym z pkt 8 poniżej.']
+				['text', 'Termin płatności: '],
+				['field', '', 'PAYMENT_TERM_DAYS_FV', 'int'],
+				['text', ' dni od daty wpływu do siedziby Zleceniodawcy wszystkich prawidłowych i kompletnych dokumentów, o których mowa w pkt 6 i 7 poniżej w trybie zgodnym z pkt 8 poniżej.']
 			];
 			$conditions[] = [
 				['text', 'Podstawą do wystawienia przez Zleceniobiorcę na rzecz Zleceniodawcy faktury VAT jest podpisany przez obie strony bezusterkowy protokół odbioru przez Zleceniodawcę przedmiotu zlecenia oraz dostarczenie Zleceniodawcy przez Zleceniobiorcę wszelkich niezbędnych dokumentów związanych z przedmiotem zlecenia, a także w razie gdy przedmiotem zlecenia jest wynajem sprzętu – podpisana i zaakceptowana przez obie strony karta pracy sprzętu.']
@@ -1208,10 +1268,10 @@ body { font-size:12px; line-height:1.3em }
 				['text', 'Płatność dokonana będzie wyłącznie na podstawie prawidłowo wystawionej i doręczonej Zleceniodawcy przez Zleceniobiorcę faktury VAT z dołączonym oryginałem dokumentu potwierdzającego bezusterkowy odbiór przez Zleceniodawcę przedmiotu zlecenia wraz ze wszystkimi niezbędnymi dokumentami przez osoby wymienione w pkt 10 i 11 poniżej, a także w przypadku gdy przedmiotem zlecenia jest wynajem sprzętu – w oparciu o podpisaną przez osoby wymienione w pkt 10 i 11 poniżej i zaakceptowaną przez obie strony kartę pracy sprzętu, a także kopią niniejszego zlecenia podpisaną przez Zleceniodawcę i Zleceniobiorcę zgodnie z zasadami reprezentacji, poświadczoną przez Zleceniobiorcę za zgodność z oryginałem.']
 			];
 			$conditions[] = [
-				['text', 'Zleceniobiorca przekaże Zleceniodawcy fakturę VAT wraz z wymaganymi załącznikami, o których mowa w pkt 5-7 powyżej wyłącznie przesyłką poleconą Poczty Polskiej za potwierdzeniem odbioru.']
+				['bold', 'Zleceniobiorca przekaże Zleceniodawcy fakturę VAT wraz z wymaganymi załącznikami, o których mowa w pkt 5-7 powyżej wyłącznie przesyłką poleconą Poczty Polskiej za potwierdzeniem odbioru.']
 			];
 			$conditions[] = [
-				['text', 'W przypadku gdy Zleceniobiorca otrzyma dokumenty, o których mowa w pkt 5-7 powyżej, niespełniające warunków wskazanych w niniejszym zleceniu lub zostaną one wysłane niezgodnie z trybem określonym w pkt 8 powyżej, wówczas Zleceniodawca zastrzega sobie prawo do odmowy realizacji płatności i odesłania ich na adres Zleceniobiorcy celem skorygowania.']
+				['bold', 'W przypadku gdy Zleceniobiorca otrzyma dokumenty, o których mowa w pkt 5-7 powyżej, niespełniające warunków wskazanych w niniejszym zleceniu lub zostaną one wysłane niezgodnie z trybem określonym w pkt 8 powyżej, wówczas Zleceniodawca zastrzega sobie prawo do odmowy realizacji płatności i odesłania ich na adres Zleceniobiorcy celem skorygowania.']
 			];
 			$conditions[] = [
 				['text', 'Osoba do kontaktu ze strony Zleceniodawcy: '],
@@ -1288,10 +1348,10 @@ body { font-size:12px; line-height:1.3em }
 				['text', 'Płatność dokonana będzie wyłącznie na podstawie prawidłowo wystawionej i doręczonej Zamawiającemu przez Dostawcę faktury VAT z dołączonym oryginałem dokumentu potwierdzającego bezusterkowy odbiór przez Zamawiającego przedmiotu zamówienia wraz ze wszystkimi niezbędnymi dokumentami, gwarancjami, atestami, testami, etc. przez osoby wymienione w pkt 11-12 poniżej, a także kopią niniejszego zamówienia podpisaną przez Zamawiającego i Dostawcę zgodnie z zasadami reprezentacji, poświadczoną przez Dostawcę za zgodność z oryginałem.']
 			];
 			$conditions[] = [
-				['text', 'Dostawca przekaże Zamawiającemu fakturę VAT wraz z wymaganymi załącznikami, o których mowa w pkt 7 powyżej wyłącznie przesyłką poleconą Poczty Polskiej za potwierdzeniem odbioru.']
+				['bold', 'Dostawca przekaże Zamawiającemu fakturę VAT wraz z wymaganymi załącznikami, o których mowa w pkt 7 powyżej wyłącznie przesyłką poleconą Poczty Polskiej za potwierdzeniem odbioru.']
 			];
 			$conditions[] = [
-				['text', 'W przypadku gdy Zamawiający otrzyma dokumenty, o których mowa w pkt 7 i 8 powyżej, niespełniające warunków wskazanych w niniejszym zamówieniu lub zostaną one wysłane niezgodnie z trybem określonym w pkt 8 powyżej, wówczas Zamawiający zastrzega sobie prawo do odmowy realizacji płatności i odesłania ich na adres Dostawcy celem skorygowania.']
+				['bold', 'W przypadku gdy Zamawiający otrzyma dokumenty, o których mowa w pkt 7 i 8 powyżej, niespełniające warunków wskazanych w niniejszym zamówieniu lub zostaną one wysłane niezgodnie z trybem określonym w pkt 8 powyżej, wówczas Zamawiający zastrzega sobie prawo do odmowy realizacji płatności i odesłania ich na adres Dostawcy celem skorygowania.']
 			];
 			$conditions[] = [
 				['text', 'Zamawiającemu przysługuje prawo do naliczenia Dostawcy kary umownej w wysokości '],
@@ -1359,13 +1419,17 @@ body { font-size:12px; line-height:1.3em }
 <link rel="stylesheet" type="text/css" href="static/sweetalert2.min.css">
 <script src="static/sweetalert2.min.js"></script>
 <script src="stuff/vendors.js"></script>
-<script src="stuff/bundle.se_route_orders.js?_ver=67c0cabc<?php if (V::get('DBG_JS', '', $_GET)) : ?>&_ts=<?= time(); ?><?php endif; ?>"></script>
+<script src="stuff/bundle.se_route_orders.js?_ver=8b030997<?php if (V::get('DBG_JS', '', $_GET)) : ?>&_ts=<?= time(); ?><?php endif; ?>"></script>
 <script>
 (function() {
 
-var _showSendToLink = <?= ('ZATWIERDZONE' == $data['APPROVE_STATUS']) ? 'true' : 'false' ?>;
+<?php
+$showSendToLink = (in_array($data['APPROVE_STATUS'], ['OCZEKUJE_OSTATECZNEGO_ZATWIERDZENIA','ZATWIERDZONE','OCZEKUJE_ZATWIERDZENIA']));
+$sendToDealEmail = (in_array($data['APPROVE_STATUS'], ['ZATWIERDZONE'])) ? $data['COMPANY_CONTACT_MAIL'] : '';
+?>
+var _showSendToLink = <?= ($showSendToLink) ? 'true' : 'false' ?>;
 var _sendToAutorEmail = '<?= DB::getPDO()->fetchValue("select u.EMAIL from CRM_LISTA_ZASOBOW_ORDERS o join ADMIN_USERS u on(u.ADM_ACCOUNT = o.A_RECORD_CREATE_AUTHOR) where o.ID={$id_order}"); ?>';
-var _sendToDealEmail = '<?= $data['COMPANY_CONTACT_MAIL']; ?>';
+var _sendToDealEmail = '<?= $sendToDealEmail; ?>';
 var _sendToLinkLabel = "Wyślij";
 var _sendToLink = '<?= $sendToLink; ?>';
 var _mode = '<?= $mode; ?>';

+ 51 - 1
SE/se-lib/Route/ViewTableAjax.php

@@ -4,7 +4,7 @@ Lib::loadClass('RouteBase');
 Lib::loadClass('ProcesHelper');
 Lib::loadClass('TableAjax');
 // Lib::loadClass('Request');
-// Lib::loadClass('Response');
+Lib::loadClass('Response');
 Lib::loadClass('UI');
 
 class Route_ViewTableAjax extends RouteBase {
@@ -114,6 +114,56 @@ class Route_ViewTableAjax extends RouteBase {
 		UI::dol();
 	}
 
+	public function revertFromHistAjaxAction() {
+		Response::sendTryCatchJson(array($this, 'revertFromHistAjax'));
+	}
+
+	public function revertFromHistAjax() {
+		$typeName = V::get('typeName', '', $_REQUEST, 'word');
+		if (!$typeName) throw new Exception("Wrong param typeName");
+		$id = V::get('ID', '', $_REQUEST, 'word');
+		if (!$id) throw new Exception("Wrong param ID");
+		$idHist = V::get('idHist', '', $_REQUEST, 'word');
+		if (!$idHist) throw new Exception("Wrong param idHist");
+		$fieldName = V::get('fieldName', '', $_REQUEST, 'word');
+		if (!$fieldName) throw new Exception("Wrong param fieldName");
+		$acl = $this->getAclFromTypeName($typeName);
+
+		$item = $acl->getItem($id);
+		if (!$item) throw new HttpException("Item not found", 404);
+		if (!$acl->canWriteObjectField($fieldName, $record)) throw new Exception("Missing perm Write for field {$fieldName}");
+		$histItem = $acl->getHistItem($id, $idHist);
+		if (!$histItem) throw new HttpException("Hist Item not found", 404);
+
+		$histValue = V::get($fieldName, 'N/S;', $histItem);
+		if ('N/S;' == $histValue) throw new Exception("Missing field value in hist[{$idHist}] for field({$fieldName}) from item[{$id}]");
+
+		if ($acl->isGeomField($fieldName)) {
+			$wktType = strtoupper($acl->getGeomFieldType($fieldName));
+			if (!$wktType) throw new Exception("Wrong geometry type for field {$fieldName}");
+			if ($wktType != strtoupper(substr($histValue, 0, strlen($wktType)))) throw new Exception("Wrong geometry type for field {$fieldName} in hist value");
+			$coords = trim(substr($histValue, strlen($wktType)), '()');
+			$wktValue = $acl->convertGmlCoordsToWkt($wktType, $coords, ['cs'=>' ', 'ts'=>',']);
+			if (!$wktValue) throw new Exception("BUG in hist record");
+
+			$sqlObj = array();
+			$sqlObj['ID'] = $id;
+			$sqlObj[$fieldName] = "GeomFromText('{$wktValue}')";
+			$affected = DB::getDB()->UPDATE_OBJ($acl->getName(), (object)$sqlObj);
+			if (0 == $affected) throw new AlertInfoException("Nie wprowadzono żadnych zmian");
+			else if ($affected < 0) throw new Exception("Wystąpiły błędy podczas aktualizacji rekordu [{$id}]");
+			$jsonResponse = array();
+			$jsonResponse['type'] = 'success';
+			$jsonResponse['msg'] = "Zaktualizowano dane na podstawie wcześniejszej wartości dla rekordu [{$id}]";
+			$jsonResponse['actions'] = array();
+			$jsonResponse['actions'][] = ['jsFunction'=>'TableAjax__HIST_Route', 'args'=>[$id]];
+			return $jsonResponse;
+		} else {
+			throw new HttpException("Not implemented - update from hist only for the geom field", 501);
+		}
+		throw new Exception("BUG: update field '{$fieldName}' in item[{$id}] from hist[{$idHist}]", 501);
+	}
+
 	/**
 	 * @param string $typeName - 'p5_default_db:TEST_PERMS'
 	 */

+ 7 - 0
SE/se-lib/TableAcl.php

@@ -1440,6 +1440,13 @@ class TableAcl extends Core_AclBase {
 		return $ds->getHistItems($id);
 	}
 
+	public function getHistItem($id, $idHist) {
+		$ds = $this->getDataSource();
+		$histItems = $ds->getHistItems($id, ['ID' => $idHist]);
+		if (empty($histItems)) return null;
+		return reset($histItems);
+	}
+
 	public function addItem($itemTodo) {
 		if (is_object($itemTodo)) {
 			$itemTodo = (array)$itemTodo;

+ 220 - 139
SE/se-lib/TableAjax.php

@@ -3295,6 +3295,178 @@ var p5UI_TableAjax_generateFunctionNode = function(funObj, rowPK, props) {
 	$exportFields = $this->_showExportFieldsJson();
 ?>
 		<script>
+function TableAjax__HIST_Route(args) {
+	var recordID = args;
+	if (typeof args == 'object') {
+		recordID = args.shift();
+		recordID = parseInt(recordID);
+	}
+	if (typeof recordID !== 'number' || recordID <= 0) {
+		// TODO: msg
+		return false;
+	}
+	var cont = jQuery('#<?php echo $this->_htmlID; ?>').parent();
+	cont.hide();
+
+	// remove previous task content
+	var taskCnt = jQuery('#<?php echo $this->_htmlID; ?>_task');
+	taskCnt.parent().remove();
+	taskCnt.remove();
+
+	var taskCont = jQuery('<div class="AjaxTableCont"></div>').insertBefore(cont);
+	jQuery('<ul class="breadcrumb">' +
+		'<li><a href="#" onclick="return tableAjaxBackToTable();"><?php echo $this->getLabelHtml(); ?></a></li>' +
+		'<li class="active">Historia rekordu</li>' +
+	'</ul>').appendTo(taskCont);
+	var taskCnt = jQuery('<div id="<?php echo $this->_htmlID . '_task'; ?>" class="AjaxTableTaskCnt AjaxTable-loading"></div>').appendTo(taskCont);
+	jQuery('<span class="loading-info"> loading ...</span>').appendTo(taskCnt);
+
+	$.ajax({
+		dataType: 'json',
+		type: "GET",
+		url: 'index-ajax.php?_zasobID=<?php echo $this->_zasobID; ?>&_cls=<?php echo __CLASS__; ?>&_hash=<?php echo $this->_htmlID; ?>&_task=HIST&ID=' + recordID,
+	})
+	.done(function(data, textStatus, jqXHR){
+		taskCnt.removeClass('AjaxTable-loading');
+		<?php if(DBG::isActive() && V::get('DBG', '', $_GET)) : ?>console.log('TODO #L.<?= __LINE__; ?> done loading HIST_AJAX - data:', data);<?php endif; ?>
+
+		histAjaxOut = '<fieldset>' +
+			'<legend>' + data['label'] +
+				'<span class="pull-right valign-btns-bottom">';
+		for (i in data['row_functions']) {
+			histAjaxOut += data['row_functions'][i];
+			// TODO: fetch more row functions
+		}
+		histAjaxOut += '</span>' +
+			'</legend>'
+		'</fieldset>';
+		if (!data['rows']) {
+			histAjaxOut += '<div class="alert alert-info">' +
+				'<h4>Brak danych</h4>' +
+			'</div>';
+		} else {
+			histAjaxOut += '<table class="table table-striped table-hover table-bordered table-condensed AjaxTableHist">' +
+				'<thead>' +
+					'<tr>' +
+						'<th>Data</th>' +
+						'<th>User</th>' +
+						'<th>Zmiany</th>' +
+					'</tr>' +
+				'</thead>' +
+				'<tbody>';
+			for (i in data['rows']) {
+				var row = data['rows'][i];
+				histAjaxOut += '<tr data-id_hist="' + row['ID'] + '">' +
+					'<td style="white-space:nowrap">' + row['_created'] + '</td>' +
+					'<td>' + row['_author'] + '</td>' +
+					'<td>';
+				for (j in row['changes']) {
+					var change = row['changes'][j];
+					var fieldName = change['fieldName'];
+					if (['ID', 'A_RECORD_UPDATE_DATE', 'A_RECORD_UPDATE_AUTHOR', 'A_RECORD_CREATE_DATE', 'A_RECORD_CREATE_AUTHOR'].indexOf(fieldName) >= 0) continue;
+					if ('N/S;' == change['value']) continue;
+					histAjaxOut += '<p>' +
+						'<em>' + (data['field_label'][fieldName] || fieldName) + '</em>: ';
+					histAjaxOut += (change['acl_read'])
+							? change['value']
+							: '<span title="Brak uprawnień do odczytu tego pola">*****</span>'
+					if (change['revert_function_url']) {
+						histAjaxOut += ' <button' +
+								' class="btn btn-xs btn-default"' +
+								' onClick="return p5UI__ajaxLinkClick(this, \''+change['revert_function_url']+'\', \''+change['revert_function_data']+'\')"' +
+								' title="Cofnij dane do tej wartości">' +
+								'<i class="glyphicon glyphicon-floppy-disk"></i> cofnij' +
+							'</button>';
+					}
+					histAjaxOut += '</p>';
+				}
+				histAjaxOut += '</td>' +
+				'</tr>';
+			}
+			histAjaxOut += '</tbody>' +
+			'</table>';
+		}
+
+		{// old view - flat table
+			histAjaxOut += '<div style="overflow-x:scroll; overflow-y:visible; padding-bottom:1px; margin:10px 0;">' +
+				'<table class="table table-striped table-hover table-bordered table-condensed AjaxTableHist">' +
+					'<thead>' +
+						'<tr>';
+			for (j in data['fields']) {
+				var fieldName = data['fields'][j];
+				histAjaxOut += '<th>' + (data['field_label'][fieldName] || fieldName).replace('_', ' ') + '</th>';
+			}
+			histAjaxOut += '</tr>' +
+					'</thead>' +
+					'<tbody>';
+			for (i in data['rows']) {
+				var row = data['rows'][i];
+				histAjaxOut += '<tr>';
+				for (j in data['fields']) {
+					var fieldName = data['fields'][j];
+					histAjaxOut += '<td>';
+					( (!(fieldName in row['changes']) || row['changes'][fieldName]['value'] == 'N/S;')
+							? histAjaxOut += '<em>N/S;</em>'
+							: ( (row['changes'][fieldName]['acl_read'])
+									? histAjaxOut += row['changes'][fieldName]['value']
+									: histAjaxOut += '<span title="Brak uprawnień do odczytu tego pola">*****</span>'
+								)
+						);
+					histAjaxOut += '</td>';
+				}
+				histAjaxOut += '</tr>';
+			}
+			histAjaxOut += '</tbody>' +
+				'</table>' +
+			'</div>';
+		}
+		jQuery(histAjaxOut).appendTo(taskCnt);
+	})
+	.fail(function(jqXHR){// jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {});
+		taskCnt.removeClass('AjaxTable-loading');
+		if (jqXHR.responseJSON) {
+			notifyAjaxCallback(jqXHR.responseJSON);
+		}
+		else {
+			var txt = jqXHR.responseText || 'Wystąpiły błędy';
+			if (jqXHR.status == 404) {
+				jQuery.notify(jqXHR.responseText, 'error');
+			} else {
+				jQuery.notify(jqXHR.responseText, 'warn');
+			}
+		}
+		console.log('TODO #L.<?= __LINE__; ?> fail loading HIST_AJAX - jqXHR.responseText:', jqXHR.responseText);
+	});
+
+	function notifyAjaxCallback(data) {
+		var notify = {};
+		notify.type = (data && data.type)? data.type : '';
+		notify.msg = (data && data.msg)? data.msg : '';
+		switch (notify.type) {
+			case 'success':
+				if (!notify.msg) notify.msg = 'OK';
+				break;
+			case 'info':
+				if (!notify.msg) notify.msg = '';
+				break;
+			case 'error':
+				if (!notify.msg) notify.msg = 'Wystąpiły błędy';
+				break;
+			case 'warning':
+				notify.type = 'warn';
+				if (!notify.msg) notify.msg = 'Wystąpiły błędy';
+				break;
+			default:
+				notify.msg = 'Nieznany błąd';
+				if (data && data.errorCode) notify.msg += ' ' + data.errorCode;
+				notify.type = '';
+		}
+		jQuery.notify(notify.msg, notify.type);
+	}
+	//return false;
+}
+		</script>
+		<script>
 jQuery(document).ready(function(){
 	jQuery('#<?php echo $this->_htmlID; ?>').TableAjax({
 		url: 'index-ajax.php?_zasobID=<?php echo $this->_zasobID; ?>&_cls=<?php echo __CLASS__; ?>&_hash=<?php echo $this->_htmlID; ?>',
@@ -3391,50 +3563,7 @@ jQuery(document).ready(function(){
 
 					//return false;
 				},
-				HIST: function(args) {
-					var recordID = args;
-					if (typeof args == 'object') {
-						recordID = args.shift();
-						recordID = parseInt(recordID);
-					}
-					if (typeof recordID !== 'number' || recordID <= 0) {
-						// TODO: msg
-						return false;
-					}
-					var cont = jQuery('#<?php echo $this->_htmlID; ?>').parent();
-					cont.hide();
-
-					// remove previous task content
-					var taskCnt = jQuery('#<?php echo $this->_htmlID; ?>_task');
-					taskCnt.parent().remove();
-					taskCnt.remove();
-
-					var taskCont = jQuery('<div class="AjaxTableCont"></div>').insertBefore(cont);
-					jQuery('<ul class="breadcrumb">' +
-						'<li><a href="#" onclick="return tableAjaxBackToTable();"><?php echo $this->getLabelHtml(); ?></a></li>' +
-						'<li class="active">Historia rekordu</li>' +
-					'</ul>').appendTo(taskCont);
-					var taskCnt = jQuery('<div id="<?php echo $this->_htmlID . '_task'; ?>" class="AjaxTableTaskCnt AjaxTable-loading"></div>').appendTo(taskCont);
-					jQuery('<span class="loading-info"> loading ...</span>').appendTo(taskCnt);
-
-					jQuery.ajax({
-						url: 'index-ajax.php?_zasobID=<?php echo $this->_zasobID; ?>&_cls=<?php echo __CLASS__; ?>&_hash=<?php echo $this->_htmlID; ?>&_task=HIST&ID=' + recordID,
-						type: 'GET',
-						dataType: 'text',
-						data: '',
-						async: true,
-						success: function(data) {
-							taskCnt.removeClass('AjaxTable-loading');
-							//console.log('request finished L.<?php echo __LINE__; ?>');
-							jQuery(data).appendTo(taskCnt);
-						},
-						error: function(err) {
-							taskCnt.removeClass('AjaxTable-loading');
-							//console.log('request error: {0}'.f(err));
-						}
-					});
-					//return false;
-				},
+				HIST: TableAjax__HIST_Route,
 				FILES: function tableAjaxFiles(args) {
 					var recordID = args;
 					if (typeof args == 'object') {
@@ -3859,12 +3988,7 @@ function <?php echo $jsToogleFiltrProcesuFunctionName; ?>(n) {
 				break;
 			}
 			case 'HIST': {
-				$id = V::get('ID', 0, $_REQUEST, 'int');
-				if ($id > 0) {
-					$this->sendAjaxHistory($id, $_REQUEST);
-				} else {
-					echo '404';
-				}
+				$this->sendAjaxResponseJson('ajaxHist', $_REQUEST);
 				break;
 			}
 			case 'FILES': {
@@ -4685,108 +4809,65 @@ jQuery(document).ready(function(){
 		return $response;
 	}
 
-	private function sendAjaxHistory($id, $args) {
-		header("Content-type: text/plain");
-
-		$record = $this->_acl->getItem($id);
-		if (!$record) {
-			header('HTTP/1.0 404 Not Found');
-			echo "404: No item ID({$rowID})";
-			exit;
-		}
+	private function ajaxHist($args) {
+		$jsonResponse = array();
+		$id = V::get('ID', 0, $args, 'int');
+		$acl = $this->_acl;
+		$record = $acl->getItem($id);
+		if (!$record) throw new HttpException("404: No item ID({$id})", 404);
 
-		$visibleCols = $this->_acl->getRealFieldList();
-		$rowsHist = $this->_acl->getHistItems($id);
+		$visibleCols = $acl->getRealFieldList();
+		$rowsHist = $acl->getHistItems($id);
 
-		$rowFunctionsOut = $this->_showRowFunctions($record->ID, array('hist', 'cp'), true);
+		$jsonResponse['row_functions'] = $this->_parseRowFunctions($record->ID, array('hist', 'cp'), $showLabel = true);
 
 		$visibleColsWithIds = array();
 		$visibleColsLabels = array();
 		foreach ($visibleCols as $vColName) {
-			$fldId = $this->_acl->getFieldIdByName($vColName);
+			$fldId = $acl->getFieldIdByName($vColName);
 			if ($fldId) {
 				$visibleColsWithIds[$fldId] = $vColName;
-				$label = $this->_acl->getFieldLabel($fldId);
+				$label = $acl->getFieldLabel($fldId);
 				$label = (!$label)? $vColName : '<span title="' . "[{$fldId}] {$vColName}" . '">' . $label . '</span>';
 				$visibleColsLabels[$fldId] = $label;
 			}
 		}
+		$jsonResponse['label'] = "Historia rekordu Nr {$id}";
+		$jsonResponse['fields'] = array_values($visibleColsWithIds);
+		$jsonResponse['field_label'] = $visibleColsLabels;
+
+		if (empty($rowsHist)) return $jsonResponse;
+
+		$jsonResponse['rows'] = array();
+		foreach ($rowsHist as $row) {
+			$histItem = array();
+			$histItem['ID'] = $row->ID;
+			$histItem['_created'] = $row->_created;
+			$histItem['_author'] = $row->_author;
+			$histItem['changes'] = array();
+			foreach ($visibleColsWithIds as $fldId => $fieldName) {
+				// if (in_array($fieldName, array('ID', 'A_RECORD_UPDATE_DATE', 'A_RECORD_UPDATE_AUTHOR', 'A_RECORD_CREATE_DATE', 'A_RECORD_CREATE_AUTHOR'))) continue;
+				// if ($row->{$fieldName} == 'N/S;') continue;
+				$changeItem = array();
+				$changeItem['fieldName'] = $fieldName;
+				$changeItem['acl_read'] = $acl->isAllowed($fldId, 'R', $record);
+				if ($changeItem['acl_read']) {
+					$changeItem['value'] = $row->{$fieldName};
+				}
+				if ('the_geom' == $fieldName && $acl->isAllowed($fldId, 'W', $record)) {
+					$sourceName = $acl->getSourceName();
+					if ('default_db' == $sourceName) {
+						$typeName = $acl->getName();
+						$changeItem['revert_function_url'] = Request::getPathUri() . "index.php?_route=ViewTableAjax&typeName=p5_{$sourceName}:{$typeName}&_task=revertFromHistAjax&ID={$id}&idHist={$row->ID}&fieldName={$fieldName}";
+						$changeItem['revert_function_data'] = "ID={$id}&idHist={$row->ID}&fieldName={$fieldName}";
+					}
+				}
+				$histItem['changes'][$fieldName] = $changeItem;
+			}
+			$jsonResponse['rows'][] = $histItem;
+		}
 
-		?>
-		<fieldset>
-			<legend>Historia rekordu Nr <?php echo $id; ?>
-				<span class="pull-right valign-btns-bottom"><?php echo $rowFunctionsOut; ?></span>
-			</legend>
-		</fieldset>
-
-		<?php if (empty($rowsHist)) : ?>
-			<div class="alert alert-info">
-				<h4>Brak danych</h4>
-			</div>
-		<?php else: ?>
-		<table class="table table-striped table-hover table-bordered table-condensed AjaxTableHist">
-			<thead>
-				<tr>
-					<th>Data</th>
-					<th>User</th>
-					<th>Zmiany</th>
-				</tr>
-			</thead>
-			<tbody>
-			<?php foreach ($rowsHist as $row) : ?>
-				<tr>
-					<td style="white-space:nowrap"><?php echo $row->_created; ?></td>
-					<td><?php echo $row->_author; ?></td>
-					<td>
-					<?php foreach ($visibleColsWithIds as $fldId => $colName) : ?>
-						<?php if (in_array($colName, array('ID', 'A_RECORD_UPDATE_DATE', 'A_RECORD_UPDATE_AUTHOR', 'A_RECORD_CREATE_DATE', 'A_RECORD_CREATE_AUTHOR'))) continue; ?>
-						<?php if ($row->$colName == 'N/S;') continue; ?>
-						<p><em><?php echo $visibleColsLabels[$fldId]; ?></em>:
-							<?php if ($this->_acl->isAllowed($fldId, 'R', $record)) : ?>
-								<?php echo $row->$colName; ?>
-							<?php else : ?>
-								<span title="Brak uprawnień do odczytu tego pola">*****</span>
-							<?php endif; ?>
-						</p>
-					<?php endforeach; ?>
-					</td>
-				</tr>
-			<?php endforeach; ?>
-			</tbody>
-		</table>
-
-		<div style="overflow-x:scroll; overflow-y:visible; padding-bottom:1px; margin:10px 0;">
-		<table class="table table-striped table-hover table-bordered table-condensed AjaxTableHist">
-			<thead>
-				<tr>
-				<?php foreach ($visibleColsWithIds as $fldId => $colName) : ?>
-					<th><?php echo str_replace('_', ' ', $visibleColsLabels[$fldId]); ?></th>
-				<?php endforeach; ?>
-				</tr>
-			</thead>
-			<tbody>
-			<?php foreach ($rowsHist as $row) : ?>
-				<tr>
-				<?php foreach ($visibleColsWithIds as $fldId => $colName) : ?>
-					<td>
-						<?php if ($row->$colName == 'N/S;') : ?>
-							<em>N/S;</em>
-						<?php elseif ($this->_acl->isAllowed($fldId, 'R', $record)) : ?>
-							<?php echo $row->$colName; ?>
-						<?php else : ?>
-							<span title="Brak uprawnień do odczytu tego pola">*****</span>
-						<?php endif; ?>
-					</td>
-				<?php endforeach; ?>
-				</tr>
-			<?php endforeach; ?>
-			</tbody>
-		</table>
-		</div>
-		<?php endif; ?>
-
-		<?php
-		exit;
+		return $jsonResponse;
 	}
 
 	public function ajaxFileUpload($args) {

+ 5 - 1
SE/se-lib/Typespecial.php

@@ -684,6 +684,10 @@ jQuery('#typeahead-{$fName}').typeahead({
 			}
 		$out .= '</select>';
 		$out .= '</div>';
+
+		$ajaxDataUrlBase = "index-ajax.php?_cls=TableAjax&_zasobID={$tblID}&_task=TYPESPECIAL&fldID={$this->fldID}";
+		$ajaxDataUrlBase = V::get('ajaxDataUrlBase', $ajaxDataUrlBase, $params);
+
 		$out .= '<script>' . "
 (function(){
 	var fldNode=jQuery('#{$fName}'), tsNode=jQuery('#ts-{$fName}');
@@ -778,7 +782,7 @@ jQuery('#typeahead-{$fName}').typeahead({
 		load: function(query, callback) {
 			//if (!query.length) return callback();
 			$.ajax({
-				url: 'index-ajax.php?_cls=TableAjax&_zasobID={$tblID}&_task=TYPESPECIAL&fldID={$this->fldID}',
+				url: '{$ajaxDataUrlBase}',
 				data: 'q=' + encodeURIComponent(query),
 				type: 'POST',
 				error: function() {

+ 81 - 0
SE/se-lib/tmpl/_layout_gora.php

@@ -197,6 +197,87 @@ function p5UI__ButtonAjax(n, eventNamespace, props) {
 	return false;
 }
 
+function p5UI__ajaxLinkClick(n, href, data) {
+	if (!n || !href) return true;
+
+	var dbg = <?php echo (DBG::isActive())? 1 : 0; ?>;
+	var $n = jQuery(n);
+	if ($n.hasClass('disabled')) {// bootstrap already prevent this action
+		if(dbg)console.log('WARNING: btn disabled - waiting for response - Cancel?');
+		return false;
+	}
+	$n.removeClass('btn-primary').addClass('disabled btn-loading');
+
+	var req = superagent
+		.post(href)
+		.type('json') // header ĺapplication/x-www-form-urlencoded' requires type('form');
+		.send(data)
+		.set('Accept', 'application/json')
+		.end(function(err, res) {
+			if(dbg)console.log('DBG: res:', res, 'res.body:', res.body);
+			$n.removeClass('disabled btn-loading').addClass(state.baseCssClassNames);
+			var payload;
+			if (err || !res.ok || 'application/json' !== res.type) {
+				payload = {type: 'warning', msg: res.body.msg || 'Request error', body: res.body};
+			} else {
+				payload = {type: 'success', msg: res.body.msg || '', body: res.body};
+			}
+			if(dbg)console.log('DBG: before p5UI__notifyAjaxCallback:', payload);
+			p5UI__notifyAjaxCallback(payload);
+			if(dbg)console.log('DBG: before actions:', payload.body.actions);
+			if (payload.body.actions) {
+				for (i in payload.body.actions) {
+					p5UI__execAction(payload.body.actions[i]);
+				}
+			}
+			req = null;
+		});
+	return false;
+}
+
+function p5UI__execAction(action) {
+	var dbg = <?php echo (DBG::isActive())? 1 : 0; ?>;
+	if(dbg)console.log('DBG: action:', action);
+	if ('jsFunction' in action) {
+		if (action['jsFunction'] in window) {
+			if(dbg)console.log('TODO: exec "window[\''+action['jsFunction']+'\']( '+action['args']+' )"');
+			window[ action['jsFunction'] ]( action['args'] );
+		}
+		else {
+			if(dbg)console.log('BUG: jsFunction not exists "'+action['jsFunction']+'"');
+		}
+	} else {
+		if(dbg)console.log('TODO: action', action);
+	}
+}
+
+function p5UI__notifyAjaxCallback(data) {
+	var notify = {};
+	notify.type = (data && data.type)? data.type : '';
+	notify.msg = (data && data.msg)? data.msg : '';
+	switch (notify.type) {
+		case 'success':
+			if (!notify.msg) notify.msg = 'OK';
+			break;
+		case 'info':
+			if (!notify.msg) notify.msg = '';
+			break;
+		case 'error':
+			if (!notify.msg) notify.msg = 'Wystąpiły błędy';
+			break;
+		case 'warning':
+			notify.type = 'warn';
+			if (!notify.msg) notify.msg = 'Wystąpiły błędy';
+			break;
+		default:
+			notify.msg = 'Nieznany błąd';
+			if (data && data.errorCode) notify.msg += ' ' + data.errorCode;
+			notify.type = '';
+	}
+	jQuery.notify(notify.msg, notify.type);
+}
+
+
 function p5Utils__parseFloatOrZero(strToParse) {
 	if (!strToParse) return 0
 	if ("string" === typeof strToParse) {

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
SE/stuff/bundle.se_route_orders.js


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff